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

C++20中如何模拟std::views::zip同时消费两个std::ranges?

C++20下替代std::views::zip的优雅方案

最优方案:用std::views::zip_transform直接完成配对+构造

C++20标准里其实提供了更贴合你需求的工具——std::views::zip_transform,它可以直接对多个范围的对应元素执行变换,完全不需要先zip再transform,代码更简洁:

namespace views = std::views;

std::vector<int> a0{1,2,3,4};
std::vector<int> b0{6,7,8,9};

auto a = a0 | views::transform(foo); // foo和bar为自定义函数
auto b = b0 | views::transform(bar); 

// 直接将两个范围的对应元素传入lambda构造Object
auto objects = views::zip_transform(
    [](auto&& elem_a, auto&& elem_b) {
        return Object{std::forward<decltype(elem_a)>(elem_a), std::forward<decltype(elem_b)>(elem_b)};
    }, 
    a, b
);

zip_transform会自动遍历两个范围的对应位置元素,直到其中一个范围耗尽,完美替代你原本想用zip+transform实现的逻辑。

手动迭代配对方案(不推荐,仅作备选)

如果因为某些原因不想用zip_transform,可以手动用迭代器遍历两个范围,生成视图:

namespace ranges = std::ranges;
namespace views = std::views;

std::vector<int> a0{1,2,3,4};
std::vector<int> b0{6,7,8,9};

auto a = a0 | views::transform(foo);
auto b = b0 | views::transform(bar);

// 生成配对视图的lambda
auto make_objects_view = [&]() {
    auto it_a = ranges::begin(a);
    auto it_b = ranges::begin(b);
    const auto min_size = std::min(ranges::size(a), ranges::size(b));

    return views::generate([=, &a, &b]() mutable -> Object {
        auto obj = Object{*it_a, *it_b};
        ++it_a;
        ++it_b;
        return obj;
    }) | views::take(min_size);
};

auto objects = make_objects_view();

这个方法需要手动处理迭代器递增和范围长度边界,不如zip_transform简洁,仅作为特殊场景下的备选。

关于你尝试的iota_view方案

你之前用iota_view配合std::get的思路行不通,因为std::get<>()的索引参数必须是编译期常量,而iota_view生成的i是运行时变量,编译器无法通过。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 11:25:34