C++ - Ranges & Views Advanced
Overview
Estimated time: 70–90 minutes
Build expressive pipelines with C++20 ranges: filter, transform, take/drop, chunk, slide. Understand ownership, borrowed ranges, and when to materialize.
Learning Objectives
- Compose view pipelines and avoid dangling by materializing when needed.
- Use adaptors like views::filter, transform, take/drop, chunk, slide.
- Understand borrowed_range and range concepts in practice.
Prerequisites
View pipelines
#include
#include
#include
int main(){
std::vector v{1,2,3,4,5,6};
auto pipe = v | std::views::filter([](int x){return x%2==0;})
| std::views::transform([](int x){return x*x;})
| std::views::take(2);
for (int x: pipe) std::cout << x << ' '; // 4 16
}
Chunk and slide
#include
#include
#include
int main(){
std::vector v{1,2,3,4,5};
for (auto chunk : v | std::views::chunk(2)){
int sum = 0; for (int x : chunk) sum += x; std::cout << sum << ' '; // 3 7 5
}
std::cout << "\n";
for (auto win : v | std::views::slide(3)){
std::cout << win[0] << '+' << win[1] << '+' << win[2] << ' ';
}
}
Borrowed ranges and dangling
#include
#include
std::ranges::take_view make_view(){
std::vector tmp{1,2,3,4};
return std::views::all(tmp) | std::views::take(2); // dangling! tmp dies
}
Fix: materialize into a container before returning, or return an owning view.
Common Pitfalls
- Returning non-owning views to temporary containers (dangling).
- Assuming pipelines materialize; views are lazy until copied to a container.
Checks for Understanding
- When must you materialize a view?
- What causes dangling in ranges?
Show answers
- When you need ownership or to outlive the source; or you need random access into a non-random-access view.
- Returning a non-owning view referring to objects that will be destroyed.
Exercises
- Use chunk and transform to compute moving sums; compare slide vs manual indexing.
- Write a function that returns a materialized vector from a view pipeline to avoid dangling.