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

如何使用匿名Lambda对多个Range执行统一处理?

解决方案:将匿名Lambda批量应用到多个Range

核心实现:可变参数模板版本

利用C++20的Range概念和可变参数折叠表达式,可以快速实现符合你需求的函数,代码简洁且完全基于标准库:

#include <ranges>
#include <utility>

// 依次将可调用对象应用到每个传入的Range
template <std::ranges::input_range... Ranges, typename Callable>
void for_each_range(Ranges&&... ranges, Callable&& func) {
    // 折叠表达式遍历每个Range,调用std::ranges::for_each
    (std::ranges::for_each(std::forward<Ranges>(ranges), std::forward<Callable>(func)), ...);
}

使用示例

直接传递多个Range和末尾的匿名Lambda即可,支持修改Range元素:

#include <vector>
#include <array>
#include <iostream>

int main() {
    std::vector<int> vec{1, 2, 3};
    std::array<int, 3> arr{4, 5, 6};
    int raw_arr[] = {7, 8, 9};

    // 匿名多行Lambda,批量修改所有Range的元素
    for_each_range(vec, arr, raw_arr, [](int& x) {
        x *= 2;
        std::cout << x << ' ';
    });
    // 输出:2 4 6 8 10 12 14 16 18
}

为什么这个方案符合你的诉求

  • Lambda位于参数末尾:完全对齐std::ranges::for_each等标准算法的参数顺序,符合C++编程习惯
  • 支持修改Range:通过完美转发(std::forward)保留Range的可修改属性,避开了std::initializer_list的const限制
  • 无需命名Lambda:直接传递匿名多行Lambda,不用为临时逻辑强行命名
  • 类型安全:编译期检查每个Range是否满足input_range要求,Lambda是否能处理Range的元素类型,避免运行时错误
  • 灵活兼容:支持不同类型的Range(vector、array、原生数组等)同时传入

标准库是否有现成方案

C++标准库目前没有直接提供这种“将同一可调用对象依次应用到多个独立Range”的算法,但上述实现完全基于标准库的std::ranges::for_each和可变参数模板特性,没有额外依赖,代码量极小,相当于对标准库功能的轻量封装。

关于std::views::zip的思路

std::views::zip的设计目标是并行遍历多个Range的对应位置元素(比如同时处理vec[0]、arr[0]、raw_arr[0]),和你需求的“对每个Range单独完整执行一遍Lambda”场景不匹配,因此确实不适用。

可选:支持初始化列表语法的版本(限同类型Range)

如果坚持想要{r1, r2, r3}的初始化列表语法,可以通过包装器绕开std::initializer_list的const限制,但该版本仅支持同类型的Range:

#include <ranges>
#include <initializer_list>
#include <utility>

// 包装非const的Range引用
template <typename Range>
struct RangeRef {
    Range& ref;
    explicit RangeRef(Range& r) : ref(r) {}
};

// 辅助函数简化包装
template <typename Range>
RangeRef<Range> wrap(Range& r) {
    return RangeRef<Range>(r);
}

// 接受初始化列表的版本
template <typename Range, typename Callable>
void for_each_range(std::initializer_list<RangeRef<Range>> ranges, Callable&& func) {
    for (auto&& r : ranges) {
        std::ranges::for_each(r.ref, std::forward<Callable>(func));
    }
}

使用方式:

for_each_range({wrap(vec), wrap(arr), wrap(raw_arr)}, [](int& x) { x *= 2; });

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 06:33:21