On Mon, Dec 1, 2014 at 3:22 AM, Olaf van der Spek
On Mon, Dec 1, 2014 at 2:31 AM, Matt Calabrese
wrote: I think this kind of reasoning isn't very fruitful. Optional is not a string, string is not an optional. One having operator< does not imply the other should have it to.
Hmm? What isn't reasonable is arbitrarily deciding what should and should not have a default ordering (not talking about operator< since that's a
True, but it's NOT an arbitrary decision, is it?
It is arbitrary until and unless people actually explain what they feel is the difference between cases that they consider "reasonable" and "unreasonable." This is particularly true when one container that uses a lexicographical compare is considered "reasonable" while another container that uses a lexicographical compare is considered "unreasonable." Why you want a default order is generally analogous in both situations and denying one while not the other without any objective rationale is a very weak decision. All types can be ordered and all types that have more than one value can be ordered in multiple ways. No particular ordering is is applicable in all situations for any type -- even integers. That does not mean that a default is unimportant since frequently you require ordering for a datastructure or algorithm to work, but the actual ordering may be unimportant to the user or to the implementation. This is the whole point, which I mentioned in every single reply.
much more controversial matter). The notion of default ordering is useful because many datastructures and algorithms can make use of it, particularly
What std datastructures use it?
The ones that we've been talking about for the entire thread in almost every reply. I'm not going to repeat again.
those in the standard. There is absolutely nothing wrong with ordering
tuples or optionals or variants, or any type at all.
That's what you keep saying but you don't back it up.
Again, I have done so multiple times in this thread, both with concrete examples and with reference to why it is important in more generic code. You can choose to put your fingers in your ears if you want, but that changes nothing. Frankly, it's sort of unfortunate that the usefulness of ordering for /any/ type needs to be re-explained in the context of C++, since it's such a fundamental concept that has been talked about many times before, not just by myself in this thread but by key C++ people, i.e. Stepanov. Especially when you are creating a generic composite type that you expect people to use, you should be conscious of ordering.
The only thing you
accomplish by not having a default ordering is that you arbitrarily make the type difficult to use with these datastructures and algorithms. The
Having to explicitly pass in a comparator is not difficult is it?
As explained, it is both needless and can also be an arbitrary decision even in non-generic code, let alone in generic code where all you usually care about is that an ordering exists rather than what that particular ordering is. Ideally you always forward the comparator along when writing generic code that needs ordering, using a default of std::less just as the standard does for its generic containers, and yet the default is still useful. In fact, default comparators are so useful in the standard library that plenty of C++ programmers don't even know that the comparators are template arguments at all, yet they get along fine. I doubt that explicitly passing the comparator is "not difficult" to them. Regardless, stating that explicitly passing an argument where a default can be used is "not difficult" is a cop-out since you can always say the same thing regarding any default in any context. In this particular context, that hypothetical lack of a default comparator for the types in question has already led to the recommendation of preferring entirely different associative datastructures over passing in an explicit comparator in this very thread (ironically, the other containers that were recommended also depend on a subjective default, only it's the default hashing function instead of the default ordering function). You should not be afraid to have your types be ordered when they can be ordered. Most decisions in development have a subjective aspect to them and precisely which default ordering comparator you provide is just one of those many decisions. The fact that a default is subjective (and it always is, even for arithmetic types), does not mean that a default is not useful. Why do we use less as a default for arithmetic types with respect to a set? Wouldn't greater be just as sensible? What about the other orderings? We only accept that it is "reasonable" now to have less be the default ordering because that was the decision that was made decades ago and people are used to it. It. Is. Just. A. Default. -- -Matt Calabrese