From: Herve Bronnimann (hbr_at_[hidden])
Date: 2002-09-03 15:25:15
On Tue, Sep 03, 2002 at 10:38:35PM +0300, Peter Dimov wrote:
> > The user should be forced to realize that he has left total orderings
> > and went into the land of partial orderings, where the "if !(a <= b)"
> > and "if (a > b)" equivalence does not hold. Such shortcuts are *only*
> > allowed in total orderings, else we would end up with the rather
> > unpleasant "(a <= b) != (a < b || a == b)", which is the case here...
> You are certainly aware that the STL defines a >= b as !(a < b), aren't you?
Let me point out that this was THE argument in favor of our "wrong"
choice. What David is suggesting amounts to no less than contradicting
the C++ standard, IMHO.
For instance, e.g. in the SGI STL implementation (and I am not quite
sure this is mandated by the standard, but it is certainly a legal
implementation, insofar as the elements concerned below), the
max_element is computed in terms of operator<, but std::greater in terms
of operator>. Defining operator> in terms other than semantically
different from !operator< leads to:
max_element(first, last) != min_element(first, last, std::greater<T>).
I am sure it is more feasible to document this dilemma (as we have done
in the chapter on comparisons) and to encourage the use of explicit
comparisons such as cerlt (or certainly_less_than) when a certain
semantics is desired.
> The "pleasant"
> a <= b :- a < b || a == b
> implies the existence of a == b (and that a == b is consistent with a < b).
One consequence of defining a>b as !(a<b) is that a==b means `a and b
overlap', which is certainly an equivalent relation, and in the spirit
of the distinction equality vs. identity drawn by the STL.
The STL itself formulates its algorithms so that only operator< is used,
with the consequences above that two elements are found equivalent when
neither is less than the other one. We have only tried to follow that
> In situations where <= is ambiguous, I usually define only < (not even >)
> and let the user disambiguate explicitly.
That would be another choice with which we were confronted. But as a
convenience, we defined the four operators. Also because as a numeric
type, one expects all the four comparison operators to be defined.
Indeed Boost::concept_check defines ComparableConcept with all four
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk