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

C++ -- lambda捕获

C++ Lambda 捕获分为‌基础捕获‌、‌混合捕获‌、‌特殊捕获‌和‌C++14/20 新特性‌。

1. 基础捕获:值 vs 引用

A. 空捕获[]

不访问任何外部变量。

int x = 10; auto f = ‌:ml-search[] { // std::cout << x; // 错误!x 未捕获 return 42; };
B. 按值捕获[x]

拷贝外部变量。‌内部修改不影响外部‌,且默认不可修改(除非加mutable)。

int x = 10; auto f = ‌:ml-search[x] { // x = 20; // 错误!按值捕获的变量是 const 的 return x; }; // x 仍然是 10
C. 按值捕获 + mutable[x] mutable

允许修改‌副本‌,但‌不影响外部变量‌。

int x = 10; auto f = ‌:ml-search[x] mutable { x = 20; // 合法,修改的是内部副本 return x; }; std::cout << f() << std::endl; // 输出 20 std::cout << x << std::endl; // 输出 10 (外部未变)
D. 按引用捕获[&x]

直接引用外部变量。‌内部修改直接影响外部‌。需注意生命周期(悬空引用风险)。

int x = 10; auto f = ‌:ml-search[&x] { x = 20; // 合法,直接修改外部 x return x; }; f(); std::cout << x << std::endl; // 输出 20 (外部已变)

2. 默认捕获与混合捕获(最常用)

E. 默认按值捕获[=]

Lambda 体内用到的所有局部变量都按值拷贝。

int a = 1, b = 2; auto f = ‌:ml-search[=] { return a + b; };

注意:在 C++11/14 中,[=]也会隐式捕获this指针(如果使用了成员变量)。

F. 默认按引用捕获[&]

Lambda 体内用到的所有局部变量都按引用绑定。

int a = 1, b = 2; auto f = ‌:ml-search[&] { a++; b++; // 直接修改外部变量 };
G. 混合捕获:默认值 + 特定引用[=, &x]

场景‌:大部分变量只需读取(拷贝开销小或需要快照),但某个大对象或需要修改的变量使用引用。

int a = 1; std::vector<int> huge_vec(1000000); // 大对象 auto f = ‌:ml-search[=, &huge_vec] { // a 是拷贝(安全,快照) // huge_vec 是引用(避免拷贝百万级数据,且可修改) huge_vec.push_back(a); };
H. 混合捕获:默认引用 + 特定值[&, x]

场景‌:大部分变量需要修改外部状态,但某个变量(如 ID、配置)需要保留创建时的副本,防止外部意外修改。

int id = 100; int status = 0; auto f = ‌:ml-search[&, id] { status = 1; // 修改外部 status // id = 200; // 错误!id 是 const 副本 std::cout << "ID at creation: " << id << std::endl; }; id = 999; // 外部修改 id f(); // 输出: ID at creation: 100 (内部仍保留旧值)

3. 类成员与this指针

I. 捕获this[this]

在类成员函数中,若要访问成员变量,必须捕获this

class MyClass { int val = 10; public: void doWork() { // auto f = ‌:ml-search[val] {}; // 错误!C++11/14/17 不能直接捕获成员变量 auto f = ‌:ml-search[this] { val = 20; // 通过 this->val 访问 }; f(); } };

风险:如果MyClass对象销毁了,但 Lambda 还被持有(例如在线程池中),调用 Lambda 会导致 Crash。

J. C++20 新特性:按值捕获*this[*this]

解决上述风险‌。它会拷贝整个对象到 Lambda 内部。

// C++20 auto f = ‌:ml-search[*this] { val = 20; // 修改的是 Lambda 内部拷贝的对象,不影响原对象 };

优点:安全,无悬空指针。缺点:如果对象很大,拷贝开销大。

4. C++14 初始化捕获(Init Capture / Generalized Capture)

这是 C++14 引入的强大功能,允许在捕获列表中‌定义新变量‌并初始化。它解决了“移动语义”和“重命名”的问题。

K. 移动捕获(Move Capture)

用于捕获不可拷贝的对象(如std::unique_ptr)。

auto ptr = std::make_unique<int>(100); // auto f = ‌:ml-search[ptr] {}; // 错误!unique_ptr 不可拷贝 auto f = ‌:ml-search[p = std::move(ptr)] { std::cout << *p << std::endl; }; // ptr 现在为空,所有权已转移给 Lambda 内部的 p
L. 捕获表达式结果

可以捕获任意表达式的结果,甚至给变量起别名。

int x = 10; // 捕获 x 的两倍,并存入名为 doubled_x 的新变量 auto f = ‌:ml-search[doubled_x = x * 2] { return doubled_x; };
M. 捕获引用(C++14)

虽然 C++11 有[&x],但 C++14 允许更灵活的引用初始化。

int x = 10; auto f = ‌:ml-search[&ref_x = x] { ref_x = 20; };
http://www.gsyq.cn/news/1410768.html

相关文章:

  • 大语言模型采样策略全解析:从原理到实战配置指南
  • 构建本地化AI文本检测与人性化改写工具:从句子级高亮到精准干预
  • AI智能体工具库扩展:分层路由与动态编排架构设计实践
  • 【ChatGPT面试通关黄金法则】:20年技术面试官亲授5大高频陷阱与3步反杀话术
  • 别再为不规则模型头疼了!用Abaqus手动切分与扫掠网格,快速实现软体机器人仿真
  • 巨有科技:乡村市集的 “在地化” 密码——跳出同质化,做有根的烟火气
  • AI结构化推理:从“诚实失败”到深度思考的工程实践
  • 恢复 Windows 7 的经典照片查看器(Windows Photo Viewer)
  • 告别低效加班,ChatGPT帮你重写日程表:基于1762名知识工作者行为数据的时间优化模型
  • 2026年知名的SAUER绍尔空压机维修保养/康普艾空压机维修保养/电力空压机维修保养长期合作厂家推荐 - 行业平台推荐
  • 巨有科技县区级旅游大数据方案|数据治旅,破解县域文旅粗放运营难题
  • AI原生运维操作系统:重构SRE工作流,实现智能告警与自动化
  • 从SolidWorks到Matlab仿真:一个工业机器人(IRB2600)URDF模型的全链路制作与调试实录
  • 避坑指南:在Ubuntu 20.04上安装Cartographer ROS时,如何手动搞定那个恼人的.rosinstall文件?
  • Flutter SharedPreferences 本地存储详解
  • 期刊论文写作心得:巧用辅助工具,解锁学术撰文的高效之道
  • 【ChatGPT商业竞争格局解码】:用波特五力模型穿透AI大模型赛道的护城河与生死线
  • 从被动执行到主动驱动:如何构建自我驱动的思维与行动框架
  • MathType装完Word里不显示?可能是Office的‘信任中心’在搞鬼,5分钟教你设置好
  • OpenAPI x-agent-trust扩展:为AI智能体构建API信任机制
  • Keil C51内存重叠警告(L5)解析与解决方案
  • MySQL排序规则(Collation)详解:从一次SQL注入报错讲起,如何避免和排查字符集问题
  • STM32CubeMX外部中断配置避坑指南:从引脚模式到回调函数,新手常犯的5个错误
  • 使用 Taotoken CLI 工具一键配置多开发环境下的 API 访问密钥
  • 蓝桥杯单片机DS18B20温度测量:从数据手册到四位小数显示的完整代码解析(含负数处理)
  • 2026年 雨水井模具/污水井模具/阀门井模具/电信井模具/电缆井模具/圆井模具/检查井模具/方井模具/拼装方井模具厂家推荐:质量过硬与工艺精度口碑之选 - 品牌企业推荐师(官方)
  • RTX51与C51版本兼容性问题解析与解决方案
  • SARscape实战:手把手教你处理.hgt格式SRTM DEM,解决干涉处理报错难题
  • 智能体架构设计:MCP与A2A协议的分层协作与选型指南
  • 基于硬件在环的并联逆变器系统实时稳定性分析与在线监测