On 16 October 2013 16:23, Christopher Jefferson <chris@bubblescope.net> wrote:
On 16 October 2013 16:06, Gabriel Dos Reis <gdr@microsoft.com> wrote:

> |
> | So what about std::less<void>?  Should people be using it?
>
> What is wrong about it?
>

Just to clarify this problem (because I don't think anyone has
described the problem in detail).

Given two int* pointers x,y;

std::less<int*>()(x,y) is defined and a total ordering.

std::less<>()(x,y) invokes undefined behaviour, as it is defined as
calling 'x<y'.

It does not invoke ub, as there are weasel words forcing this to work correctly for pointers.

Therefore std::less<> is not a drop in replacement for std::less<int*>.

std::less<> can be a drop in replacement for std::less<int*>.

In general though, std::less<>::operator()(T const&, T const&) is not a drop in replacement for std::less<T>::operator()(T const&, T const&), even though it is intended to be.  This is problematic.
 
This is also hard to fix, as std::less<> can take different types, so
it can't just always delegate to std::less<T> for the actual type T
being compared.

Well, it could for the case I wrote above, but that would be more than an editorial change to C++14, and definitely a breaking change after C++14 ships.
 
I was under the impression this problem was generally known, but had
been ignored for some reason I did not know, as I do not attend
meetings.

I don't remember it coming up in Bristol when we discussed it.  It isn't the only place in the standard library that uses operator< instead of std::less; I'd rather see that addressed in one go.

I certainly have no plans to bring up any issues with less<>.

Then again, my advice to developers is to forget about less<T> (that route lies madness) and just write an operator< for their class so they'll never see the problem.  However, this advice differs from the advice of Gaby and Sean.
--
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  (847) 691-1404