From: David Bergman (davidb_at_[hidden])
Date: 2002-09-03 15:36:10
The C++ Standard gives us a default implementation of "<=" in terms of
"! >". That default behavior should be overridden when that is no longer
true w.r.t. logic. That is why I used the hard word "wrong", cause it is
"wrong" as in illogical to have (in a domain with proper equivalence)
a <= b != a < b || a == b
Note that The C++ Standard often assumes total orderings in its default
behavior. A lot of the algorithms provided by The C++ Standard are only
operable on total orderings. So, by following the default STL behavior
for this relation will only cause headache further down the road, when
the user through STL and its algorithms end up with [3, 5] being
equivalent to [4, 6].
Whether logical is "right" or not is another question, so excuse me for
using the word "wrong"; I should have stuck to illogical.
[mailto:boost-bounces_at_[hidden]] On Behalf Of Herve Bronnimann
Sent: Tuesday, September 03, 2002 4:25 PM
Subject: Re: [boost] Formal Review for Interval Library beginning
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,
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
-- Hervé _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk