HOWTO · C++
How to Sort Vector in C++
This article introduces how to sort vector in C++
On this page
To sort a std::vector in C++, call std::sort with the vector’s begin() and end() iterators. By default, elements are ordered using operator<. For a type with a different ordering rule, pass a comparator that says whether its first argument should come before its second.
Sort a vector with std::sort
std::sort rearranges elements in the half-open range from the first iterator up to, but not including, the last iterator. A std::vector supplies the random-access iterators this algorithm requires. Include <algorithm> for std::sort; the example also includes <iostream> for printing and <vector> for the container. With no comparator argument, the algorithm uses the element type’s default ordering, commonly expressed by operator<.
Run this example:
#include <algorithm>
#include <cstddef>
#include <iostream>
#include <vector>
int main() {
std::vector<int> values{8, 3, 6, 1, 5};
std::sort(values.begin(), values.end());
for (std::size_t index = 0; index < values.size(); ++index) {
if (index != 0) {
std::cout << ' ';
}
std::cout << values[index];
}
std::cout << '\n';
}
1 3 5 6 8
Use the same iterator range for the whole vector, or pass iterators delimiting a portion when only part of it should be sorted. The range must be valid, and its last iterator is excluded. The default ordering is useful for numbers and for types that already define the order you want. For records, select a field explicitly with a comparator.
Sort records with a lambda comparator
A lambda keeps a short comparison rule next to the sort that uses it. In this example, Task records are ordered by their priority field. The comparator receives two records and returns true when the first should precede the second. Its parameters are const references because comparison does not need to modify either record.
Run this example:
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
struct Task {
std::string name;
int priority;
};
int main() {
std::vector<Task> tasks{{"write", 3}, {"review", 1}, {"build", 2}};
std::sort(tasks.begin(), tasks.end(),
[](const Task& left, const Task& right) {
return left.priority < right.priority;
});
for (const Task& task : tasks) {
std::cout << task.name << ':' << task.priority << '\n';
}
}
review:1
build:2
write:3
The comparison rule must establish a strict weak ordering: it must behave consistently, and an element is not considered to come before itself. Comparing an integer field with < gives ascending priority order. Reversing the operands changes the direction. If you call std::sort again with a different comparator, that call rearranges the current range according to the new rule; successive calls do not combine their keys into a multi-field ordering. When multiple criteria are needed, express the full rule in one comparator.
Use a named comparator for reusable rules
When the same rule is used in several places, give it a name. A function object with a const call operator can be passed to std::sort just like a lambda. This example orders tasks by name, so the comparator can be reused wherever that rule is needed.
Run this example:
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
struct Task {
std::string name;
int priority;
};
struct ByName {
bool operator()(const Task& left, const Task& right) const {
return left.name < right.name;
}
};
int main() {
std::vector<Task> tasks{{"write", 3}, {"review", 1}, {"build", 2}};
std::sort(tasks.begin(), tasks.end(), ByName{});
for (const Task& task : tasks) {
std::cout << task.name << ':' << task.priority << '\n';
}
}
build:2
review:1
write:3
A named comparator is useful when its logic deserves a descriptive name or must be shared by multiple sorting calls. Keep its ordering consistent with the data and use const-reference parameters for read-only comparisons. For a one-off field comparison, the lambda is usually more direct. In either form, the comparator controls the order; the default operator< is used only when no comparator is supplied.