Algorithms and Ranges
Algorithms and Ranges
Searching, sorting, transforming, and filtering with the STL and modern ranges.
Algorithms and Ranges
Searching, sorting, transforming, and filtering with the STL and modern ranges.
std::sort(values.begin(), values.end());
auto it = std::find(values.begin(), values.end(), 42);
int count = std::count(values.begin(), values.end(), 0);
std::reverse(values.begin(), values.end());
std::vector<int> doubled(values.size());
std::transform(values.begin(), values.end(), doubled.begin(),
[](int x) { return x * 2; });
bool any_negative = std::any_of(values.begin(), values.end(),
[](int x) { return x < 0; });
namespace views = std::views;
auto even_squares = values
| views::filter([](int x) { return x % 2 == 0; })
| views::transform([](int x) { return x * x; });
std::span or ranges for non-owning access patterns.auto pos = std::ranges::find(values, 42);
std::ranges::sort(values);
auto sum = std::accumulate(values.begin(), values.end(), 0);
std::ranges::* algorithms accept ranges directly.struct User { std::string name; int score; };
std::ranges::sort(users, std::greater<>{}, &User::score);
auto active_names = users
| std::views::filter([](const User& user) { return user.score > 0; })
| std::views::transform([](const User& user) { return user.name; });
std::vector when you need stable storage or repeated traversal over a changing source.std::ranges::* algorithms when you already have a range object and want cleaner call sites or projectionsstruct User {
std::string name;
int score;
};
auto top_names = users
| std::views::filter([](const User& user) { return user.score >= 90; })
| std::views::transform([](const User& user) { return user.name; });
That shape is the common ranges pipeline: filter first, project second, and only materialize if the calling code needs owned strings or repeated traversal.
std::vector<std::string> names;
for (const auto& name : top_names) {
names.push_back(name);
}
Keep the lazy pipeline inside one stage of the program, then materialize right before you cross into storage, caching, or an API that expects owned values.
#include <algorithm>
#include <ranges>
#include <vector>
int main() {
std::vector<int> values{3, 1, 2, 4};
auto even = values | std::views::filter([](int value) { return value % 2 == 0; });
return std::ranges::find(even, 4) != even.end() ? 0 : 1;
}
Replace the hand-written search loop with a ranges pipeline. It highlights when composition improves clarity and when it becomes too indirect.
#include <ranges>
#include <vector>
int main() {
std::vector<int> values{1, 2, 3, 4, 5, 6};
auto odd = values | std::views::filter([](int value) { return value % 2 == 1; });
return *odd.begin();
}