There is a sort() method for lists in STL. Which is absurd, because I would be more inclined to sort an array/vector. Why isn't sort() provided for vector? Is there some underlying philosophy behind the creation of the vector container or its usage, that sort is not provided for it?
-
3It's not exactly a duplicate, but AndreyT's answer to [why there is no find for vector in C++](http://stackoverflow.com/questions/2994073/why-there-is-no-find-for-vector-in-c) is related. – James McNellis Dec 03 '10 at 06:37
-
2Actually a better question would be: "Why does `list` have a `sort()` method? Why can you not just use `std::sort()` like with `vector`s and arrays?" Also not sure why you think it's "absurd" to want to sort a list. – j_random_hacker Dec 03 '10 at 07:51
-
@j_random_hacker: The absurdity is probably because of the way I view the reason for using a list, in my mind. I view it as something like links of a chain connected together, which have to be disconnected before re-arranging, as compared to vector, which I view like a pack of cards which can be shuffled easily. My perception...it will get clearer when I'm familiar with programming with lists. – Nav Dec 04 '10 at 05:27
-
1Interestingly if the individual objects are sufficiently large, it will be faster to sort a list of them than a vector, because you only need to change the links (each being 1 or 2 pointers) rather than copy around entire objects. – j_random_hacker Dec 05 '10 at 00:44
-
@j_random_hacker: I agree. That's a point worth noting too.. – Nav Dec 06 '10 at 04:13
6 Answers
As has already been said, the standard library provides a nonmember function template that can sort any range given a pair of random access iterators.
It would be entirely redundant to have a member function to sort a vector. The following would have the same meaning:
std::sort(v.begin(), v.end());
v.sort();
One of the first principles of the STL is that algorithms are not coupled to containers. How data is stored and how data is manipulated should be as loosely coupled as possible.
Iterators are used as the interface between containers (which store data) and algorithms (which operate on the data). In this way, you can write an algorithm once and it can operate on containers of various types, and if you write a new container, the existing generic algorithms can be used to manipulate its contents.
The reason that std::list
provides its own sort
function as a member function is that it is not a random accessible container; it only provides bidirectional iterators (since it is intended to represent a doubly linked list, this makes sense). The generic std::sort
function requires random access iterators, so you cannot use it with a std::list
. std::list
provides its own sort
function in order that it can be sorted.
In general, there are two cases in which a container should implement an algorithm:
If the generic algorithm cannot operate on the container, but there is a different, container-specific algorithm that can provide the same functionality, as is the case with
std::list::sort
.If the container can provide a specific implementation of the algorithm that is more efficient than the generic algorithm, as is the case with
std::map::find
, which allows an element to be found in the map in logarithmic time (the genericstd::find
algorithm performs a linear search because it cannot assume the range is sorted).

- 348,265
- 75
- 913
- 977
-
1[There may be other reasons to implement a container-specific algorithm; those are just the two big ones that come to mind when looking over the STL containers] – James McNellis Dec 03 '10 at 06:35
-
2+1, but surely a better solution would have been to make `std::sort()` hand off to a static function in a class templated on the iterator's container type. The base class template would provide the random-access-requiring implementation as a default, but (being a class template) it could be partially specialised for `list
`. This framework would allow anyone who designs a container to also supply a function for sorting it that is reachable via `std::sort()`, so there would be no need for confusingly adding `sort()` as a method to some classes and not others. – j_random_hacker Dec 03 '10 at 07:47 -
@j_random_hacker: I'm not convinced that approach would be generic enough to support all possible containers. Consider a container where iterators are not sufficient to perform the sort and where you need access to the container itself (I don't think this is a problem for a typical `list` implementation, but you could definitely implement a sequence container where this was the case). – James McNellis Dec 03 '10 at 07:58
-
1
-
2in that case, maybe you want a different sort(...) algorithm that takes whole containers and can be specialized on them. – Neil G Dec 03 '10 at 07:59
-
> _The following would have the same meaning_ sort is unstable while list::sort is stable (Doesn't matter in a lot of cases and not taking anything away from this answer but remember this point guys) – pratikpc Oct 02 '20 at 18:23
There are already interesting elements of answer, but there is actually more to be said about the question: while the answer to "why doesn't std::vector
has a sort
member function?" is indeed "because the standard library provides member functions only when they offer more than generic algorithms", the real interesting question is "why does std::list
have a sort
member function?", and a few things haven't been explained yet: yes, std::sort
only works with random-access iterators and std::list
only provides bidirectional iterators, but even if std::sort
worked with bidirectional iterators, std::list::sort
would still offer more. And here is why:
First of all,
std::list::sort
is stable, whilestd::sort
isn't. Of course there is stillstd::stable_sort
, but it doesn't work with bidirectional iterators either.std::list::sort
generally implements a mergesort, but it knows that it is sorting a list and can relink nodes instead of copying things. A list-aware mergesort can sort the list in O(n log n) time with only O(log n) additional memory, while your typical mergesort (such asstd::stable_sort
) uses O(n) additional memory or has a O(n log² n) complexity.std::list::sort
doesn't invalidate the iterators. If an iterator was pointing to a specific object in the list, it will still be pointing to the same object after the sort, even if its position in the list isn't the same than before the sort.Last but not least,
std::list::sort
doesn't move or swap the objects around since it only relinks nodes. That means that it might be more performant when you need to sort objects that are expensive to move/swap around, but also that it can sort a list of objects that aren't even moveable, which is totally impossible forstd::sort
!
Basically, even if std::sort
and std::stable_sort
worked with bidirectional or forward iterators (and it would totally be possible, we know sorting algorithms that work with them), they still couldn't offer everything std::list::sort
has to offer, and they couldn't relink nodes either since the standard library algorithms aren't allowed to modify the container, only the pointed values (relinking nodes counts as modifying the container). On the other hand, a dedicated std::vector::sort
method wouldn't offer anything interesting, so the standard library doesn't provide one.
Note that everything that has been said about std::list::sort
is also true for std::forward_list::sort
.

- 21,684
- 12
- 93
- 152
A vector-specific sort would provide no advantage over std::sort
from <algorithm>
. However, std::list
provides its own sort
because it can use the special knowledge of how list
is implemented to sort items by manipulating the links instead of copying objects.

- 333,147
- 50
- 533
- 760
-
+1, but surely a better solution would have been to make `std::sort()` hand off to a static function in a class templated on the iterator's container type. The base class template would provide the random-access-requiring version of `sort()` as a default, but (being a class template) it could be partially specialised for `list
`. This framework would allow anyone who designs a container to also supply a function for sorting it that is reachable via `std::sort()`. – j_random_hacker Dec 03 '10 at 07:45
You can easily sort a vector
with:
sort(v.begin(), v.end());
UPDATE: (answer to the comment): Well, they have certainly provided it by default. The difference is that it's not a member function for vector
. std::sort
is a generic algorithm that's supposed to work for anything that provides iterators. However, it really expects a random access iterator to sort efficiently. std::list
, being a linked list, cannot provide random access to its elements efficiently. That's why it provides its own specialized sort algorithm.

- 414,610
- 91
- 852
- 789
-
I'm asking why they didn't provide it by default for vector, like how they did for list. There's obviously some reason. – Nav Dec 03 '10 at 06:16
-
And the reason is exactly what @Mehrdad said. it is provided outside the class. The question you should be asking is why they didn't do the same for `list` ;) – jalf Dec 03 '10 at 06:47
-
`vector
vec;` how to sort it using `std::sort(vec.begin(), vec.end())`? overriding the less than operator doesn't work neither :S `bool operator < (const MyClass& obj) const { return (x < obj.x); }` – StarDust Feb 02 '13 at 18:37
std::sort()
in <algorithm>
does sorting on containers with random access iterators like std::vector
.
There is also std::stable_sort()
.
edit - why does std::list
have its own sort()
function versus std::vector
?
std::list
is different from both std::vector
and std::deque
(both random access iterable) in how it's implemented, so it contains its own sort
algorithm that is specialized for its implementation.

- 77,184
- 16
- 165
- 176
-
I'm asking why they didn't provide sort by default, like how they did for list – Nav Dec 03 '10 at 06:17
-
@Nav - `std::list` is different from both `std::vector` and `std::deque` (both random access iterable) in how it's implemented, so it contains its own `sort` algorithm that is specialized for its implementation. – wkl Dec 03 '10 at 06:21
Answering the question of "Why?"
A sorting algorithm for std::vector is the same as sorting a native array and is the same (probably) as sorting a custom vector class.
The STL was designed to separate containers and algorithms, and to have an efficient mechanism for applying an algorithm to data that has the right characteristics.
This lets you write a container that might have specific characteristics, and to get the algorithms free. Only where there is some special characteristic of the data that means the standard algorithm is unsuitable is a custom implementation supplied, as in the case of std::list.

- 17,976
- 1
- 43
- 61