以下简单程序编译并运行:
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);
}
但是,如果我将生成器存储在变量中并尝试相同的操作,它不会编译:
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);
}
根据我的理解,这是失败的,因为
std::ranges::viewable_range<std::generator<int>&>
的计算结果为 false
,而 std::ranges::viewable_range<std::generator<int>&&>
的计算结果为 true。但为什么第一种情况被禁止呢?我知道 generator
不是一个范围,但它的行为就像我测试的一个和所有其他范围类型(尽管我只测试了一些)在作为左值引用传递时满足此约束。那么为什么在这种情况下让generator
变得特别呢?
std::generator
是一个仅移动的 range
,带有已删除的复制构造函数,您需要将其移动到 zip_view
:
for (auto [i, f] : std::views::zip(std::move(ints), floats))
std::println("{}: {}", i, f);