Re: [boost] Please don't define a fake"operator<"just for ordered containers

Sean Parent wrote:
From item 6 - I'd remove the operator < from shared_ptr. If we were going to keep operator < for shared ptr, then I would have to argue to change all of the examples from 6 for consistency (or provide a semantic difference between shared_ptr and these cases.
There are two problems with using std::less instead of operator< to supply a set/map order. First, it doesn't propagate to composite types; if you provide a specialization of less<K>, less< pair<K, int> > doesn't work. Well the same is true for operator < and a simple struct. I'm
Second, less<K> is defined as always using K::operator< unless K is a raw pointer; it is basically a different name for operator<, one that can be used as a predicate. This gives rise to the interpretation that wherever less<K> is encountered, the implementation is entitled to use K::operator< directly. Not true. 10.3.3.8 gives a fair amount of leeway in the case where operator < does not provide a total ordering (a raw pointer is the only instance given in the standard). We are allowed to specialize classes in the standard with our own types. So boost::tuple could specialize std::less<> without raising any conflicts. This could have been avoided by defining a separate relation for set/map order, either as a function reachable via ADL, or as a function object, then making sure that it is defined for all standard value types. Why is this necessary? std::less<> serves us well and avoids the whole ADL mess. With suitable changes to the standard, less<K> can be made that relation, and if this happens, shared_ptr ought to also be changed to reflect that. There isn't any reason that I can find in the standard not to use less<K> for shared_ptr. It won't work with std::pair<> but I consider
proposing that the standard be extended to require std::pair<> to supply a less<> specialization. that a minor inconvenience. (should we move the discussion to the std reflector?) Sean

Sean Parent wrote:
This could have been avoided by defining a separate relation for set/map order, either as a function reachable via ADL, or as a function object, then making sure that it is defined for all standard value types.
Why is this necessary? std::less<> serves us well and avoids the whole ADL mess.
std::less is ambiguous. It could be that you wanted merely the function object representation of operator<, or it could be that you wanted the default map/set ordering relation. It is not clear which of the two std::less is supposed to be. To give you an example, what would you expect std::greater<K> to do? less_equal<K>?

"Peter Dimov" <pdimov@mmltd.net> writes:
Sean Parent wrote:
This could have been avoided by defining a separate relation for set/map order, either as a function reachable via ADL, or as a function object, then making sure that it is defined for all standard value types.
Why is this necessary? std::less<> serves us well and avoids the whole ADL mess.
std::less is ambiguous. It could be that you wanted merely the function object representation of operator<, or it could be that you wanted the default map/set ordering relation. It is not clear which of the two std::less is supposed to be.
If shared_ptr doesn't support operator< it's not a problem, is it? You only get into trouble, AFAICT, when operator< and less are both available but they do different things. -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
"Peter Dimov" <pdimov@mmltd.net> writes:
Sean Parent wrote:
This could have been avoided by defining a separate relation for set/map order, either as a function reachable via ADL, or as a function object, then making sure that it is defined for all standard value types.
Why is this necessary? std::less<> serves us well and avoids the whole ADL mess.
std::less is ambiguous. It could be that you wanted merely the function object representation of operator<, or it could be that you wanted the default map/set ordering relation. It is not clear which of the two std::less is supposed to be.
If shared_ptr doesn't support operator< it's not a problem, is it?
The context is: - If we had a separate relation for set/map we would use that for settable/mappable objects. - Why is a separate relation better than just using less<>? - Because it is evident from the design of the standard library that less<> isn't meant for that, not consciously, at least. "What should shared_ptr do" is a separate question. Under the current status quo, it defines operator< to order pair< shared_ptr<>, int > as well. Under a revised standard, it may well need to do something else, depending on how the standard is changed.
participants (3)
-
David Abrahams
-
Peter Dimov
-
Sean Parent