当前位置: 首页 > news >正文

lambda 表达式

C++ 的 lambda 表达式 是一种轻量、内联的函数对象写法,广泛用于标准算法、自定义回调、事件响应等场景。它简洁且强大。以下将系统、详细地讲解 lambda 的语法、捕获规则、应用技巧和实际使用场景。


🧠 一、基本语法

[捕获列表](参数列表) -> 返回类型 { 函数体 };

示例:

auto add = [](int a, int b) -> int { return a + b; }; std::cout << add(2, 3); // 输出:5


🧩 二、捕获列表详解

捕获列表([])用于访问外部变量。可以按值、按引用捕获,也可以使用默认捕获。

捕获方式对比:

写法含义示例变量是否可修改?示例
[]不捕获[](){}
[=]按值捕获所有外部变量否(默认)[=]() { return x + y; }
[&]按引用捕获所有外部变量[&]() { x += 1; }
[x]按值捕获指定变量[x]() { return x; }
[&x]按引用捕获指定变量[&x]() { x++; }
[=, &y]默认按值,y按引用混合[=, &y]() { y += x; }
[&, x]默认引用,x按值混合[&, x]() { z += x; }

⚠ 注意:

  • 按值捕获的变量在 lambda 定义时被拷贝(或移动),后续外部变量改变不影响 lambda。

  • 要在 lambda 中修改按值捕获的变量,需加上 mutable

    [x]() mutable { x++; } // 修改的是 lambda 内部的拷贝


🔧 三、参数列表与返回类型

[](int a, int b) -> int { return a + b; }

  • 参数列表可省略,适用于无参 lambda:[] { return 42; }

  • 返回类型可省略,C++ 会自动推导(从 return 表达式)

  • return 有多个分支(如 if/else),需要显式指定返回类型


🎯 四、常见用法

1. 在 std::sort 中排序

std::vector<int> v = {3, 1, 4}; std::sort(v.begin(), v.end(), [](int a, int b) { return a < b; });

2. 与 STL 算法结合

std::vector<int> v = {1, 2, 3, 4}; auto it = std::find_if(v.begin(), v.end(), [](int x) { return x > 2; });

3. 与 for_each 连用

std::for_each(v.begin(), v.end(), [](int x) { std::cout << x << " "; });

4. 可修改外部变量(引用捕获)

int sum = 0; std::for_each(v.begin(), v.end(), [&sum](int x) { sum += x; });

5. 返回 lambda 并使用

auto make_adder = [](int x) { return [x](int y) { return x + y; }; }; auto add5 = make_adder(5); std::cout << add5(3); // 输出:8


🛠 五、高级技巧

1. 使用 mutable 修改按值捕获变量

int x = 10; auto f = [x]() mutable { x += 5; // 修改的是 x 的副本 std::cout << x; }; f(); // 输出 15;原始 x 不变

2. 带状态的闭包

auto counter = [i = 0]() mutable { return ++i; }; std::cout << counter(); // 1 std::cout << counter(); // 2

3. Lambda 与函数指针转换

auto f = [](int x) { return x * 2; }; int (*fp)(int) = f; // 仅限于不捕获的 lambda(无状态)

4. 递归 lambda(C++14 起)

std::function<int(int)> fib = [&](int n) { return (n <= 1) ? 1 : fib(n - 1) + fib(n - 2); };


🧪 六、lambda 捕获的实质(闭包对象)

Lambda 表达式是编译器自动生成的匿名类对象,包含:

  • 成员变量(捕获的变量)

  • 重载的 operator() 方法(函数体)

int a = 5; auto f = [a](int x) { return x + a; };

编译器会生成类似:

struct __Lambda { int a; __Lambda(int a_) : a(a_) {} int operator()(int x) const { return x + a; } };


✅ 总结

特性说明
[]捕获外部变量(值/引用/混合)
()定义参数列表
mutable允许修改值捕获的副本
-> type指定返回类型(可省略)
可嵌套/递归支持
与 STL 高度集成sort, for_each, find_if

相关文章:

  • 在一台CentOS服务器上开启多个MySQL服务
  • 【高并发】Celery + Redis异步任务队列方案提高OCR任务时的并发
  • 代码随想录第40天:图论1
  • 1、mongodb-- BSON 学习和JSON性能对比
  • qml用PathView实现Cover Flow效果
  • Lightweight App Alternatives
  • 耀圣-气动带刮刀硬密封法兰球阀:攻克颗粒高粘度介质的自清洁 “利器”
  • c++中构造对象实例的两种方式及其返回值
  • 牛客练习赛138-题解
  • 机器人手臂的坐标变换:一步步计算齐次矩阵过程 [特殊字符]
  • 基于大模型预测的足月胎膜早破行阴道分娩全流程研究报告
  • 2025数维杯数学建模A题完整限量论文:空中芭蕾——蹦床运动的力学行为分析
  • 突破跨界传输瓶颈:Zynq OCM与DDR核间数据共享性能深度调优
  • Rust中记录日志:fast_log
  • 什么是分布式光伏系统?屋顶分布式光伏如何并网?
  • 软件测试的概念
  • 老旧 LabVIEW 系统升级改造
  • HTML字符串转换为React元素实现
  • 基于Transformer与SHAP可解释性分析的神经网络回归预测模型【MATLAB】
  • 基于HTML+JavaScript+CSS实现教学网站
  • 市自规局公告收回新校区建设用地,宿迁学院:需变更建设主体
  • 一热就出汗 VS 热死都不出汗的人,哪个更健康?
  • 老铺黄金拟配售募资近27亿港元,用于门店拓展扩建及补充流动资金等
  • 新华时评:任凭风云变幻,中俄关系从容前行
  • 外交部发言人就当前印巴局势答记者问
  • A股高开高走,三大股指涨超1.1%:两市成交1.3万亿元,近5000股收涨