Advanced Ranges and Views
Advanced Ranges and Views
Lazy pipelines, projections, and view-oriented design beyond basic filter/transform examples.
Advanced Ranges and Views
Lazy pipelines, projections, and view-oriented design beyond basic filter/transform examples.
auto top_scores = scores
| std::views::filter([](int score) { return score >= 90; })
| std::views::transform([](int score) { return score / 10; })
| std::views::take(5);
Views are lazy and usually cheap to compose.
That means the work happens when you iterate the result, not when you define the pipeline.
auto pipeline = values
| std::views::filter([](int value) { return value % 2 == 0; })
| std::views::transform([](int value) { return value * value; });
for (int value : pipeline) {
std::cout << value << '\n';
}
std::ranges::sort(users, std::greater<>{}, &User::score);
Use projections to avoid small one-off lambdas when sorting or searching by a member.
auto it = std::ranges::find(users, 42, &User::id);
This reads as "find the user whose id is 42" instead of forcing you to write the member access manually.
auto visible_names = users
| std::views::filter(&User::active)
| std::views::transform(&User::name);
std::vector<std::string> stored_names(visible_names.begin(), visible_names.end());
Do this when the result must survive after the source range changes or disappears.
filtertransformtakedropkeysvaluessplitauto labels = users
| std::views::filter([](const User& user) { return user.active; })
| std::views::transform([](const User& user) { return user.name; });
auto page = values | std::views::drop(offset) | std::views::take(page_size);
for (const auto& key : config | std::views::keys) {
std::cout << key << '\n';
}
auto bad_view() {
return std::vector<int>{1, 2, 3} | std::views::filter([](int x) { return x > 1; });
}
This returns a view over a temporary container, which is exactly the sort of lifetime bug ranges can hide if you are not disciplined.
#include <algorithm>
#include <vector>
int main() {
std::vector<int> values{3, 1, 2};
std::sort(values.begin(), values.end());
}
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();
}