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 acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk