Date: Wed, 16 Oct 2013 16:43:43 -0500
On 16 October 2013 16:23, Christopher Jefferson <chris_at_[hidden]>wrote:
> On 16 October 2013 16:06, Gabriel Dos Reis <gdr_at_[hidden]> 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.
> On 16 October 2013 16:06, Gabriel Dos Reis <gdr_at_[hidden]> 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_at_[hidden]> (847) 691-1404
Received on 2013-10-16 23:44:25