Understanding views from the Ranges library
Views in the Ranges library are lazy evaluated iterations over a range. Technically, they are only iterators with built-in logic, but syntactically, they provide a very pleasant syntax for many common operations.
The following is an example of how to use a view to square each number in a vector (via iteration):
auto numbers = std::vector{1, 2, 3, 4};
auto square = [](auto v) {Â return v * v; };
auto squared_view = std::views::transform(numbers, square);
for (auto s : squared_view) { Â // The square lambda is invoked here
  std::cout << s << " ";
}
// Output: 1 4 9 16
The variable squared_view
is not a copy of the numbers
vector with the values squared; it is a proxy object for numbers with one slight difference—every time you access an element, the std::transform()
function is invoked. This is why we say that a view is lazy evaluated.
From the outside, you can still iterate...