This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Remove algo duplication


On Mon, 16 Sep 2013, Christopher Jefferson wrote:

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).

std::less<void> now.

I've not been keeping track of if perfect forwarding really is perfect.

Not quite, that's the point of the example below.

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).

Note that I said prvalue, not xvalue, so there is no consumption going on. vector<bool>::iterator::operator* usually returns a prvalue.

However, if perfect forwarding preserves current behaviour, then we
should do that in C++11.

That's the easiest solution, just forward the non-predicate algorithm to the predicate-algorithm with std::less<void>() as last argument. It isn't completely equivalent to the current separate code, the question is whether it is close enough. The version with predicates on iterators is perfect (I don't think a user can observe the difference), but then the question is if it is too complicated / weird.


--
Marc Glisse


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]