为什么我不能“zip”左值“生成器”?

问题描述 投票:0回答:1

以下简单程序编译并运行:

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
变得特别呢?

c++ generator std std-ranges c++23
1个回答
1
投票

std::generator
是一个仅移动的
range
,带有已删除的复制构造函数,您需要将其移动到
zip_view
:

for (auto [i, f] : std::views::zip(std::move(ints), floats))
    std::println("{}: {}", i, f);
© www.soinside.com 2019 - 2024. All rights reserved.