You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何C++中左值std::generator无法使用std::views::zip?

关于std::generator作为左值无法用于std::views::zip的问题

先看这段可正常编译运行的代码:

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。

为什么左值情况被禁止?

  • std::generator是单次迭代的范围:它的迭代过程会消耗自身状态,一旦迭代完成,生成器就无法再产生新的值,多次迭代会导致未定义行为(比如直接返回空序列)。
  • 标准库刻意限制左值生成器的viewable_range,是为了避免用户误操作——左值变量可以被多次使用,如果允许左值生成器参与视图组合,很容易出现“重复迭代同一个生成器”的错误,而这种错误的行为很难排查。
  • 像std::vector这类常规范围是多趟迭代安全的,左值引用可以被反复迭代而不会出现问题,所以它们的左值引用能满足viewable_range约束。

解决方法

如果一定要用左值变量的生成器,可以显式用std::move将其转为右值,明确告知编译器这个生成器只会被使用一次:

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);

    // 使用std::move转换为右值
    for (auto [i, f] : std::views::zip(std::move(ints), floats))
        std::println("{}: {}", i, f);
}

内容的提问来源于stack exchange,提问作者Carsten

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 11:58:16