This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: Remove algo duplication
- From: Christopher Jefferson <chris at bubblescope dot net>
- To: "libstdc++" <libstdc++ at gcc dot gnu dot org>
- Cc: Paolo Carlini <paolo dot carlini at oracle dot com>, François Dumont <frs dot dumont at gmail dot com>
- Date: Mon, 16 Sep 2013 09:11:28 +0200
- Subject: Re: Remove algo duplication
- Authentication-results: sourceware.org; auth=none
- References: <52264074 dot 2050502 at gmail dot com> <alpine dot DEB dot 2 dot 10 dot 1309081625460 dot 3536 at laptop-mg dot saclay dot inria dot fr> <522E246F dot 5040608 at gmail dot com> <E2836BBC-F90D-4AE5-AAAB-EB3242BF030D at oracle dot com> <CA+jCFLtpCASpP1NTru=__hOQo5O-uj0m82YDqmB2wBYxspcQxA at mail dot gmail dot com> <alpine dot DEB dot 2 dot 10 dot 1309151125180 dot 3593 at laptop-mg dot saclay dot inria dot fr>
On 15 September 2013 11:41, Marc Glisse <marc.glisse@inria.fr> wrote:
> On Sun, 15 Sep 2013, Christopher Jefferson wrote:
>
>> I have not looked carefully at predefined_ops.h, but I can show you
>> some of the previous code which I know has caused problems for this
>> kind of simplification. I attach it below.
>>
>> I agree with Marc, I think templated member functions are the way to
>> go. For example, I would use objects like this:
>>
>> struct __less {
>> template<typename T, typename U>
>> bool operator()(T& t, U& u) { return t < u; }
>> };
>>
>> Note the missing 'const' on T& and U& is intentional.
>
>
> That doesn't work for input iterators that return prvalues, does it? (and
> please let's not rely on the fact that only input iterators can return
> prvalues)
Good observation. In C++11 we could use perfect forwarding (this is
"in essence" perfect forwarding in C++03). I've not been keeping track
of if perfect forwarding really is perfect.
> One good point about the iterator thing is that you know it does the same
> thing as using operator< directly, since that's what it does. An example
> where you can notice a difference is for instance with an input iterator
> whose operator* returns a prvalue and an operator< that takes its arguments
> by value. Then with *i<*j you get copy elision, whereas
> std::less<void>(*i,*j) has to perform 2 moves. We may decide to ignore this
> difference, I am just giving an example where using __less would be a
> detectable change for users.
In that situation (I had bugs caused by this before) *i<*j "consumes"
i and j, and the algorithm probably wants to go on and compare i and j
to other things in future. Therefore I'm not sure such cases will
actually usefully work for almost all standard library algorithms (of
the type we are talking about here).
However, if perfect forwarding preserves current behaviour, then we
should do that in C++11.
Chris