1. Problem It Solves
Programs often traverse related sequences in lockstep or need an index beside each element. C++23 provides lazy views instead of manual index bookkeeping or eager tuple containers. The goal is to make the relevant rule visible in code instead of relying on an assumption about what “C++23 support” means.
2. Prerequisites
Day 5: lazy views and sentinels.
Day 41: ranges consumed by containers.
3. Core Idea
zip closes a zipper one position at a time, stopping with the shortest input. zip_transform immediately applies a function, and enumerate zips a generated index with values. Read the syntax from left to right, identify the value, object, or range being transformed, and then check its resulting type, lifetime, or ownership. Standardization and implementation are separate: a C++23 mode may still lack one library component, so a feature-test macro is part of responsible portable use.
4. Minimal Syntax
for (auto [index, value] : std::views::enumerate(range)) { }5. How It Works
The sample builds the smallest expression or object needed for
zip,zip_transform, andenumerateViews.It pairs names with scores, combines numeric pairs, and enumerates values when the views exist. The compiler and library apply the relevant rule before the program observes the result.
The program prints or checks lockstep pairs and index-value pairs without an intermediate container, making the important behavior easy to verify.
6. Common Mistakes
Assuming zip continues to the longest input loses data silently; storing tuple references after the source ranges die creates dangling references.
Enabling C++23 mode without checking the relevant feature macro may select code that the installed compiler or standard library does not implement yet.
7. When to Use It
Use it when the task involves lockstep traversal of related ranges with compatible lifetimes.
Avoid it when the task involves inputs where unequal lengths are an error that must be validated explicitly before zipping.
8. Simple Example
A grade report zips student names with scores and enumerates the resulting rows for display. The downloadable program keeps the data fixed so the output can be compared without entering input.
Complete sample code
Source file
cpp23/42_zip_zip_transform_enumerate/main.cpp
#include <array>
#include <functional>
#include <iostream>
#include <ranges>
#include <string_view>
#include <version>
int main() {
#if defined(__cpp_lib_ranges_zip) && defined(__cpp_lib_ranges_enumerate)
std::array names{std::string_view{"A"}, std::string_view{"B"}};
std::array scores{7, 9};
for (auto [name, score] : std::views::zip(names, scores))
std::cout << name << ':' << score << ' ';
std::cout << '\n';
std::array left{1, 2};
std::array right{10, 20};
for (int sum : std::views::zip_transform(std::plus<>{}, left, right))
std::cout << sum << ' ';
std::cout << '\n';
for (auto [index, name] : std::views::enumerate(names))
std::cout << index << '=' << name << ' ';
std::cout << '\n';
#else
std::cout << "zip or enumerate views unavailable\n";
#endif
}
9. Key Takeaways
Separate the language rule from compiler and library availability.
Keep lifetime, ownership, and deduced types visible when they affect correctness.
Prefer the smallest syntax that communicates the intent.
Guard facilities that are not yet uniformly implemented.
10. Self-Check Questions
Easy — What is the smallest syntax in Section 4, and what main job does it perform?
Medium — Read the sample program: which value, type, or branch is observed, and why?
Hard — If one zipped range has three elements and another has five, what is the resulting size and what validation is needed when truncation is unacceptable?