Boost logo

Boost :

Subject: Re: [boost] [optional] operator<(optional<T>, T) -- is it wrong?
From: Gavin Lambert (gavinl_at_[hidden])
Date: 2014-11-30 20:49:43


On 1/12/2014 13:58, Matt Calabrese wrote:
> Anyway, why specifically do you consider a tuple having a default ordering
> as a bug? All it is is a lexicographical order, just like std::string and
> just like the other containers of the standard library. It just happens to
> be heterogenous and of a fixed size. Why do you consider it not
> "reasonable" to have a default ordering as a lexicographical ordering for
> tuples and yet consider it "reasonable" to have a default ordering as a
> lexicographical ordering for std::string? The distinction that is being
> made seems entirely arbitrary unless you or someone else can (1) specify
> unambiguously what that supposed difference actually is including how you
> would generalize that distinction, and (2) explain why such a difference is
> actually important with respect to defining a default ordering via
> std::less (or a proposed std::order). I don't buy the distinction being
> worthwhile either in practice or in theory. As far as I can tell it is
> arbitrary, inconsistent, and without any objective rationale.

Most containers do not implement ordering relations of the container
itself. String is an exception because people generally think of it as
a value type rather than as a container of chars.

Why should a std::pair<iterator, bool> have an order? In what code
would you ever try to sort by such a thing? Generically sortable tuples
and variants are similarly meaningless.

It's easy to add order comparisons in where required. It's hard to
remove them once present. This tells me that they should not be
included unless there is a clear advantage in doing so, and I am not
convinced that this is the case.

> I'm sorry, but that is simply bad programming advice. Putting a tuple in a
> set is not using the "wrong" datastructure. A tuple can be correctly
> ordered just like any other type and the same is true of optionals or
> variants. There not being a single default order that everyone would expect
> without referencing documentation is completely separate from the choice of
> whether a programmer should use a set or an unordered set. Claiming that
> this should be a reason to choose one datastructure over another is
> horrible.

Define "correctly ordered" for an arbitrary tuple. If this definition
can vary from application to application or from context to context,
then the definition should not be baked in to the tuple itself, but
instead supplied only where actually needed.

(It sounds like you are arguing that in this case the programmer should
specify the tuple type specifically with its library-mandated ordering
characteristics in mind, instead of whatever other logical field order
they prefer. Especially if different orderings are required in
different contexts, the compile-time type seems like the wrong place to
be defining this.)

If the programmer does not require ordering, then why use a container
that requires it, instead of one that does not? Unless there is some
other deficiency of unordered_set vs. set (other than relative newness
and unfamiliarity) that I am unaware of, this seems obvious to me, and
I'm not sure why you seem to oppose it so strongly.

(To me, a "set" should use equality only and should never have been
ordered in the first place, but that ship has long sailed and it's
pointless to discuss it further.)

> What's with the "want" here? Why would you not want an order? I can see not
> needing it for a certain application and not minding if it's there, but you
> make it sound like it's somehow a bad thing for it to even exist. If you
> personally don't need it then you don't have to use it.

Except that where this whole discussion began was where someone was
using it unintentionally. If it wasn't there (unless specifically
requested), that wouldn't be an issue.

Perhaps your domain is different, but in my experience wanting to sort
things (particularly in a single way) is the exception rather than the
rule. Requiring types to be internally sortable therefore seems like an
unnecessary burden.

This is starting to get quite far afield from the original issue though.
  The fundamental point was that using op< on distinct types (in this
case optional<T> and T) is more likely to be a bug than it is to be
intentional code. My generalisation was that even op< on two
optional<T>s is suspicious as some people don't seem to agree where
"none" sorts, or even what "none" means in some cases -- and because
others were arguing that it was inconsistent to define one op< without
the other.

My further generalisation was that it's probably also a bug to try to
order two variant<X,Y> where one was X and the other Y. (Sure, there
are occasions where it is useful to be able to do so. But the
programmer should do that explicitly rather than using op<, due to the
principle of least surprise, and because the required sort order may be
different in different contexts.)

And again, when I say "order" above I am referring only to op< and op>
and friends. I am *not* referring to op== and op!=, which are much more
sensible for all cases.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk