Skip to main content
๐Ÿ“œ WAYPOINT LESSON

Views and Pipelines

โญโญโญ advancedโณ 11 min read๐Ÿ“ Lesson 151 of 204

A view is a non-owning range. Adaptors compose with |; nothing runs until you iterate.

The mental model

A view is a lightweight, non-owning wrapper over elements โ€” it presents data differently without copying it. Adaptation is lazy: building the pipeline does no work; iterating pulls elements through it.

namespace rv = std::views;

int total = 0;
for (int v : rv::iota(1, 11) | rv::filter([](int x) { return x % 2 == 0; })
                             | rv::transform([](int x) { return x * x; })) {
    total += v;
}
// total == 220 โ€” squares of 2,4,6,8,10, computed one element at a time

rv::iota(1, 11) is a generated range โ€” no vector exists. filter skips; transform maps; take/drop slice; reverse walks backwards. views::all(v) materializes a container into a view when you need the boundary.

Why pipelines win

  • No intermediate containers: chained algorithm calls would build a vector per stage; views build none.
  • Single pass composition: each element flows through the whole chain before the next one starts โ€” cache-friendly and early-exit-able (take(5) stops the whole pipeline).
  • Composability: the pipeline is a value; store it, pass it, reuse it.

The costs to respect

Iteration is not free (a filter+transform chain re-tests per element); deeply nested lambdas can hurt inlining; and โ€” the big one โ€” a view does not own what it points at. That is the next lessons' subject.

โšก Now practice

Ready to Code
Pipelines and ProjectionsCompose lazy pipelines and use projections with range algorithms โ€” no intermediate containers allowed.
2 challenges ยท ยท ~22 min