Boost logo

Boost :

From: Daryle Walker (darylew_at_[hidden])
Date: 2006-07-22 06:44:05

On 7/19/06 8:02 AM, "David Abrahams" <dave_at_[hidden]> wrote:

> Daryle Walker <darylew_at_[hidden]> writes:
>> On 7/11/06 11:51 AM, "David Abrahams" <dave_at_[hidden]> wrote:
>>> "Philippe Vaucher" <philippe.vaucher_at_[hidden]> writes:
>>>> I think we should not define meaningless operator< for the
>>>> structs/whatever,
>>>> and let the user define one if he wants to use those structs in a set.
>>> That would be exceedingly inconvenient. Having a builtin operator<
>>> for tuples is a huge win for users.
>> But should a convenient lie (providing fake operators "<" to use in sets &
>> maps) trump an inconvenient truth (not providing such operators for types
>> that model an unordered concept)? Convenient lies can suddenly turn
>> inconvenient at the worst times....
> shared_ptr's operator< is neither fake nor is it a lie. The same
> applies to operator< for tuples. They are both well-specified and
> consistent with the standard's expected requirements for operator<.
> Certainly tuple, a heterogeneous container, has an operator< that's
> consistent with the ones for std::vector and std::string.
> I request that you objectively justify your use of "fake" and "lie"
> here, or that you set aside the hyperbolic language and start dealing
> with facts.

The argument I'm making is between shortcuts versus modeling. Obviously the
shared_ptr's operator "<" is consistent and provides (at least) a strict
weak ordering, otherwise it wouldn't be useful at all. The question is if
that operator is provided _solely_ for making a shortcut for programmers
that don't want to bother explicitly specify a comparison function object
for their sets and maps. Does the operator serve any use for the class
outside of the shortcut?

If there are other uses, then shared_ptr should have all the ordering
operators defined, and not just "<". (Otherwise, users would have to
contort their expressions to avoid ">", "<=", and ">=".) If there are no
uses beside this shortcut, then the ordering operator should be removed
since the class's model doesn't need it. (This is why std::complex<>
doesn't have ordering operators.) We minimize confusion by not loading
types with extra operations that the user doesn't need just so the
programmer can have a shortcut. That's why I called these controversial
operators "fake."

Almost any type in C++ can have some default lexicographic order defined for
it. (A major exception is types that are or contain unions.) That doesn't
mean that said ordering has any significance for the type's abstract model.
Ordering works mainly for models with a linear orientation. Should
non-linear models (e.g. complex numbers) have ordering operators thrust upon
them? For types like tuple, helpers for implementing other types, it's
arguable whether or not it should have ordering operators. (If a tuple does
have such operators, then a type that contains a tuple doesn't have to peek
into the tuple's implementation if it wants to use tuple's piecewise
lexicographic comparison for itself.)

The standard templates give us the ability to override the default
comparison routine. This arrangement allows comparisons of the same type
with different criteria, and gives the user a way to enable comparison with
unordered types. Said user could make a comparison function object use a
lexicographic order of the main type's sub-objects, or s/he could use
different priorities. If arbitrary ordering operators are added to a type
with an unordered model, the user still has to check how said operators work
to confirm if sorting will be made to need, and still has to define a new
comparison function object class if the user disagrees with the ordering
decisions. This makes no difference in computation (for user-defined
types), only in the amount of typing.

> As far as I can tell these operators have _never_ been shown to cause
> any problems other than violating some peoples' sense of purity.

The history of C++ has had "cute" ideas added, potentially popular, only to
discover said ideas can backfire (e.g. std::vector<bool>). I want to keep
us from adding similar mistakes; maintaining model consistency can help.

Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT hotmail DOT com

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