Advanced Ranges and Views

Advanced Ranges and Views

Build readable lazy pipelines and understand when to keep views versus materializing results.

Advanced Ranges and Views

Why ranges matter

Ranges let you express data flow directly: filter, transform, slice, then consume. This often reads closer to the problem than manual iterator code.

auto ids = users
    | std::views::filter([](const User& user) { return user.active; })
    | std::views::transform([](const User& user) { return user.id; });

Lazy vs materialized results

The pipeline above is lazy. It does not create a new container automatically.

That is useful when:

Materialize into a container when you need stable ownership or repeated traversal.

Projections simplify algorithms

std::ranges::sort(users, std::greater<>{}, &User::score);

This sorts by score without writing a custom comparator body.

A complete example

std::vector<std::string> top_names(const std::vector<User>& users) {
    auto view = users
        | std::views::filter([](const User& user) { return user.score >= 90; })
        | std::views::transform([](const User& user) { return user.name; });

    return {view.begin(), view.end()};
}

Common pitfalls

Exercises