I always wondered why there is no
sort(v);// same as std::sort(v.begin(),v.end())
If I recall correctly long time ago I saw a boostcon cli
There is nothing about this that requires concepts. Ranges are not any more complex than iterators really.
What if you only wanted to sort a subset of the container?
I almost posted a similar question recently about why for_each
isn't a member function of Container
instead of being standalone. i.e. v.for_each([&sum] (int i) { sum += i; });
It's not the std::sort(v)
-> std::sort(v.begin(), v.end())
expansion that would need concepts, but the alternate sort function taking an additional parameter for the comparison - std::sort(v.begin(), v.end(), compare)
.
If you have a call std::sort(v, compare)
, the implementation would need concepts to distinguish it from std::sort(start, end)
for a non-container.
The <algorithm>
header is full of templates with this kind of problem.
From Learning Standard C++ as a New Language (PDF) Stroustrup, C/C++ Users Journal. pp 43-54. May 1999:
Plain sort(v) would have been simpler in this case, but sometimes we want to sort part of a container so it’s more general to specify the beginning and end of what we want to sort.
That makes sense to me. It's trivial to create a wrapper, as you've demonstrated, and it's not terribly cumbersome to use without a wrapper. Having a second sort()
that took the Container just doesn't seem worth it.
<algorithm>
functions don't work on container directly. They only interacts with iterators, without any context knowledge of the container. I see no harm if you use a short full range sort notation for you own purpose, but you have to assume the object have begin / end interface, which also happen to be bidirectional iterators.
Concepts aren't required for this -- but (as they were proposed during C++11 standardization) they would have made it fairly easy to implement this.
As it stands right now, you could do this by providing a couple of extra overloads (or possibly explicit specializations) for std::sort
. The problem, of course, is that std::sort
isn't the only algorithm, so you'd undoubtedly want to do the same for lots of other algorithms as well (nearly all of them, most likely).
Concepts (specifically, concept maps, if memory serves) would have provided a fairly clean way to provide (equivalents of) all those overloads in a relatively centralized way, so you'd have all those adapters in one place instead of N places (one for each algorithm). Better still, as long as they conformed to the normal conventions, it would work for other algorithms as well.
Quite a few people currently believe ranges are the way this should be handled -- that algorithms should operate on ranges, and any container should define a range (but there should be other ways to define ranges as well). While this is probably good as a general idea, it appears (at least to me) that there's a fair amount of disagreement over the precise details of what should constitute a range, how they should be defined, etc.
If you really want to explore this, Boost already has a range library that includes range-based versions of most of the standard algorithms (and a number of others as well). At least if memory serves, this includes some adapters to create a range from a container, so things like sort(c)
will work without your having to explicitly specify a range or iterators.