The following simple program compiles and works:
std::generator<int> get_ints(int n)
{
for (int i{0}; i < n; ++i)
co_yield i;
}
int main(int argc, char* argv[])
{
std::vector<float> floats { 0.0f, 1.0f, 2.0f, 3.0f };
for (auto [i, f] : std::views::zip(get_ints(4), floats))
std::println("{}: {}", i, f);
}
However, if I instead store the generator in a variable and attempt the same, it does not compile:
std::generator<int> get_ints(int n)
{
for (int i{0}; i < n; ++i)
co_yield i;
}
int main(int argc, char* argv[])
{
std::vector<float> floats { 0.0f, 1.0f, 2.0f, 3.0f };
auto ints = get_ints(4);
for (auto [i, f] : std::views::zip(ints, floats))
std::println("{}: {}", i, f);
}
From my understanding this fails, because std::ranges::viewable_range<std::generator<int>&> evaluates to false, while std::ranges::viewable_range<std::generator<int>&&> evaluates to true. But why is the first case forbidden? I know that generator is not a range, but it behaves like one and every other range type that I tested (although I only tested a few) satisfies this constraint when passed as an lvalue reference. So why makes generator special in this case?
>Solution :
std::generator is a move-only range with a deleted copy constructor, you need to move it into the zip_view:
for (auto [i, f] : std::views::zip(std::move(ints), floats))
std::println("{}: {}", i, f);