From: Peter Dimov (pdimov_at_[hidden])
Date: 2000-09-06 09:00:35
> I find the fact that whether or not operator< gives you the same
> ordering on two separate executions is unspecified for the same set of
> ref<> objects slightly worrying.
I think that the above should be "two separate compilations", but I may be
> For type_info::before this is not a
> problem: before is not operator<.
Depends on what your intuition leads you to assume about operator<.
before() is operator<. Why call it before() if it isn't? a type_info can
never be 'before' another type_info.
"a < b" and "a is before b" are equally applicable to type_info (and ref;
"a < b" is not a magnitude comparison in the general case. It isn't a
magnitude comparison even for integers: -5 < -4.
But let's assume that ref doesn't provide operator<, because it's not
"intuitive" to some subset of users. You have proposed that I specialise
less<ref> to make the associative containers work.
I think that this is much more counter-intuitive.
std::less<>()(a, b) is defined by the standard to return a < b. Therefore,
std::sort(begin, end, std::less<>());
should be the same thing.
Had std::map been defined this way:
std::map<K, V, C = std::key_default_comparator<K> >
I wouldn't have had problems with providing key_default_comparator<ref>
while disabling ref::op<.
As it stands, however, I think that "extending" std::less to not use op< is
not acceptable. Pointers are an unfortunate exception because op< for them
is not required to provide a total ordering for historical and performance
> >> understanding, and the std only requires that the ordering is strict
> >> weak, which ref<> also does not satisfy.
> struct empty
> ref<empty> lhs(empty()), rhs(empty());
> Is lhs < rhs, rhs < lhs, lhs == rhs, or none of these?
!(lhs < rhs)
!(rhs < lhs)
Whether lhs == rhs is debatable (in terms of op==; in terms of op< they are
equivalent.) I haven't decided on this yet.
Of course, ref<> provides a strict weak ordering only if you don't
deliberately break it by putting objects with broken op< in it. This is a
reasonable assumption, IMHO.
> >> And less<T*> is, in principle, specialised for this purpose. Would you
> >> rather that pointers had this total ordering?
> >Yes. And in practice they already do on many platforms.
> That was not the question. My current platform supports operator< for
> ref<>, but I don't have to like that ;->
I answered the question. Yes, I'd rather have the total ordering. It doesn't
do any harm, is intuitive, and is a superset of the required ordering
between pointers to the same object. The "unspecifiedness" of the comparison
between pointers to different objects does not bother me. Why should it?
> >It has to be unspecified if you don't know that 'int' is an int and
> >is a double. ref does not interpret types. Neither does any.
> ref<> does interpret types, albeit in a limited fashion, otherwise you
> cannot establish any ordering.
No, it doesn't interpret types. It can only compare them for equality. The
fact that int can implicitly convert to double is well beyond that.
> The essential problem is that ref<> has a mix and match approach to its
> idea of ordering that is inconsistent: in some cases operator< is
> unspecified but provides a strict weak ordering, in others it is
> specified and provides a total ordering, and in others it is specified
> but does not provide an ordering.
ref's approach to ordering is consistent.
ref(T t) < ref(U u) iff T < U || (T == U && t < u).
Provided that t < u is strict and weak (again, a reasonable assumption),
this is a superset of the two status-quo orderings:
ref(T) < ref(U) is an unspecified total ordering different than, but with
the same properties as, type_info::before().
ref(T t1) < ref(T t2) is the strict and weak ordering between the elements
of the type T.
I don't see anything inconsistent with it.
-- Peter Dimov Multi Media Ltd.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk