Boost logo

Boost :

From: Daryle Walker (darylew_at_[hidden])
Date: 2000-09-07 14:39:48

on 9/7/00 1:25 PM, Kevlin Henney at kevlin_at_[hidden] wrote:

> In message <004501c018bc$c760c4e0$520a24d4_at_pdimov>, Peter Dimov
> <pdimov_at_[hidden]> writes
>> The standard does not assume that !(a < b) && !(b < a) implies a == b.
> True, but it's the closest to hand for an equivalence relationship.
> I think it is strange (nonintuitive, indeed) to define relational operators
> such that
> !(a < b) && !(b < a) does not imply a == b
> Don't you think? Subset and subtyping relationships often use the notation
> like this, but I think that is a questionable route and fortunately one that
> the STL chose not to follow, preferring lexicographical_compare instead. That
> said, I would prefer any of those interpretations above unspecified (and that
> preference is ordered ;->).

You can conceive of a type that the equivalence relationship won't hold. I
once thought of an iterator-like type. The iterators could support all the
relational operators (== != < > <= >=). Most of the comparisons would only
make sense if the two iterators pointed to objects in the same container.
If the objects were in two separate containers, then all of {<, >, <=, >=,
==} will return false (!= returns true), breaking your equivalence
relationship. C++'s Standard Library also assumes this kind of
relationship, so this theoretical iterator would screw-up STL. Actually,
these kind of iterators have to exist for the standard containers, but I
think C++ punts the issue my making iterator comparisons across separate
containers undefined.

To bring this more on-topic, any (and ref<T>) shouldn't have any relational
operators. In the general case, comparison between two objects is
nonsensical. The ref<T> class family has the problem that T may not allow
comparisons, or for a ref<T> and ref<U>, T-objects and U-objects may not be
comparable with each other. The any class[1] has those problems and the
complication of C++'s poor reflection capabilities prevent automatic
comparison in the first place (you would have to manually guess [with the
"type" method] and extract the values from the any-objects first).

Having no relational operators is not unprecedented, the std::complex<T>
doesn't have any ordered relational operators (<, >, <=, >=) since ordering
is nonsensical for complex numbers (but == and != do make sense, and are
provided). The moral should be: don't add something that shouldn't be there
just for convenient. In this case, it's adding operator< to ref<T> and any
just so they can be used in std::set or std::map. If the clients of
std::complex can live with needing a custom comparator for sets or maps, so
can the clients of ref and any.

[1] The any class does mistakenly have an operator<. Worse, it compares by
the type of its stored object, not its value, so different objects of the
same internal type will always compare equal!


Boost list run by bdawes at, gregod at, cpdaniel at, john at