C++STL

C++ Algorithms & Ranges: Views, Pipelines, Projections & std::ranges (C++20/23)

TT
TopicTrick Team
C++ Algorithms & Ranges: Views, Pipelines, Projections & std::ranges (C++20/23)

C++ Algorithms & Ranges: Views, Pipelines, Projections & std::ranges (C++20/23)


Table of Contents


Ranges Concepts: Range, View, and Viewable Range

mermaid

A View is a range that:

  1. Copies in O(1) — it's a non-owning reference, like std::string_view
  2. Computes lazily — no data is processed until iterated
  3. Composes with other views via |

std::ranges Algorithms: Drop the Iterator Pairs

Every std:: algorithm has a std::ranges:: equivalent that accepts the whole container:

cpp

Projections: Searching and Sorting by Member

Projections are one of the best quality-of-life features in std::ranges. Instead of writing a custom comparator lambda, you pass a member pointer or callable as the projection:

cpp

Views: Lazy Evaluation Pipelines

Views are lazy: they define how to process data but only do the work when you iterate:

cpp

Essential Views Reference

cpp

std::ranges::to: Materializing Views (C++23)

Views are lazy — to get a concrete std::vector, use std::ranges::to (C++23):

cpp

Parallel Algorithms: std::execution Policies

Standard algorithms support parallel execution via execution policies (requires TBB or compiler parallelism support):

cpp

Frequently Asked Questions

Do range views incur overhead compared to manual loops? No — the compiler fuses the entire view pipeline into a single optimized loop. The generated assembly for filter | transform | take is identical to a handwritten for loop with inline conditions. Views add zero runtime overhead vs manual loops; their only cost is slightly longer compile times.

Can I use ranges with my custom container? Yes — any container with begin() and end() returning iterators is automatically a range. For the full std::ranges feature set (projections, etc.), your iterators should model the std::input_iterator concept (or stronger). std::views::iota and std::views::generate create ranges from arbitrary generators without needing a container.

What is the difference between std::ranges::sort and std::sort? Both sort in-place. std::ranges::sort accepts the whole container (no begin/end needed), supports projections, requires std::random_access_range, and returns the sorted subrange. std::sort requires explicit iterator pairs and doesn't support projections. In new code, always prefer std::ranges::sort.


Key Takeaway

The std::ranges library is the biggest productivity and correctness improvement to C++ data processing since C++11 containers. Lazy views eliminate intermediate allocations. Projections eliminate comparator lambdas. Range algorithms eliminate begin()/end() boilerplate. Parallel execution policies add multi-core performance with a single argument change. Together, they enable Python-level expressiveness at C++ performance.

Read next: Safety First: std::span and Bounds Checking →


Part of the C++ Mastery Course — 30 modules from modern C++ basics to expert systems engineering.