STL Algorithms
Essential algorithms
Algorithm | Header | What it does |
|---|---|---|
std::sort | <algorithm> | Sorts a range in place, ascending by default |
std::find | <algorithm> | Returns an iterator to the first matching element, or end() |
std::count | <algorithm> | Counts how many elements equal a value |
std::count_if | <algorithm> | Counts how many elements satisfy a predicate |
std::accumulate | <numeric> | Folds a range into a single value (e.g. sums it) |
std::for_each | <algorithm> | Applies a function to every element |
std::transform | <algorithm> | Writes a mapped version of a range into a destination |
std::remove / erase-remove idiom | <algorithm> | Moves unwanted elements to the end (does not resize!) |
std::max_element / std::min_element | <algorithm> | Returns an iterator to the largest/smallest element |
std::reverse | <algorithm> | Reverses a range in place |
A worked example
Here is a small pipeline that sorts a vector, searches it, and then transforms it, using nothing but standard algorithms — no manual loops written by hand.
Sort, find, then transform
#include <algorithm>
#include <iostream>
#include <numeric>
#include <vector>
int main() {
std::vector<int> scores = {72, 95, 48, 61, 88};
// 1. Sort ascending
std::sort(scores.begin(), scores.end());
// 2. Find the first score of at least 80
auto it = std::find_if(scores.begin(), scores.end(),
[](int s) { return s >= 80; });
if (it != scores.end()) {
std::cout << "First score >= 80: " << *it << "\n";
}
// 3. Transform every score into a curved score (+5, capped at 100)
std::vector<int> curved(scores.size());
std::transform(scores.begin(), scores.end(), curved.begin(),
[](int s) { return std::min(100, s + 5); });
// 4. Fold: compute the average of the curved scores
int total = std::accumulate(curved.begin(), curved.end(), 0);
double average = static_cast<double>(total) / curved.size();
std::cout << "Average curved score: " << average << "\n";
return 0;
}The erase-remove idiom
remove() alone does not shrink the container
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
std::vector<int> nums = {1, 2, 3, 4, 5, 6};
// remove() shuffles kept elements to the front and
// returns an iterator marking the new logical end.
auto newEnd = std::remove(nums.begin(), nums.end(), 3);
std::cout << "Size after remove(): " << nums.size() << "\n"; // still 6!
// erase() actually shrinks the container using that iterator.
nums.erase(newEnd, nums.end());
std::cout << "Size after erase(): " << nums.size() << "\n"; // now 5
return 0;
}v.erase(std::remove(v.begin(), v.end(), value), v.end());
<algorithm> and <numeric> provide reusable, well-tested building blocks for common operations on sequences.
Algorithms operate through iterators, so the same call works across vector, list, deque, and more.
std::remove/remove_if only rearrange elements; pair them with .erase() to actually shrink the container.
Reaching for a named algorithm communicates intent better than an equivalent hand-written loop.