O seguinte programa simples compila e funciona:
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);
}
Entretanto, se eu armazenar o gerador em uma variável e tentar fazer o mesmo, ele não compila:
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);
}
Pelo que entendi, isso falha, porque std::ranges::viewable_range<std::generator<int>&>
avalia para false
, enquanto std::ranges::viewable_range<std::generator<int>&&>
avalia para true. Mas por que o primeiro caso é proibido? Eu sei que generator
não é um intervalo, mas ele se comporta como um e todos os outros tipos de intervalo que testei (embora eu tenha testado apenas alguns) satisfazem essa restrição quando passados como uma referência lvalue. Então por que makes generator
special nesse caso?
std::generator
é uma movimentação somenterange
com um construtor de cópia excluído, você precisa movê-lo parazip_view
: