当前位置: 首页 > 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.jsqmd.com/news/901380/

相关文章:

  • Make-it:基于领域知识层的AI硬件方案生成工具,降低DIY门槛
  • 不止于折线图:用Stata的twoway rcap玩转分类数据的可视化呈现
  • 从数据集到芯片:决策树模型自动化ASIC设计全流程解析
  • 量子储层GAN:NISQ时代的机器学习新突破
  • MCP服务器监控实战:像API一样构建可观测性体系
  • MVP开发成本全解析:从概念到实战的精准预算指南
  • 解决EPSON RC+ 7.0编程编译报错:从‘Integer i’到‘Jump daiji’的实战排错指南
  • 从自定义Agent到技能封装:AI工程化的高效实践路径
  • Windows安全中心“好心办坏事”?MsMpEng.exe进程深度解析与USB弹出冲突的幕后真相
  • 告别命令盲敲!用VS Code图形化界面搞定华为云Git代码上传
  • 一次真实体验:我对 CSDN AI 数字营销功能的几点感受
  • 在自动化工作流中集成Taotoken通过OpenClaw实现智能体任务调度
  • ChatGPT播客内容策划全流程拆解(含真实ROI数据看板):头部知识IP验证——用AI降本67%,完播率提升2.8倍
  • AI智能体社交推理实战:基于对抗性对话的秘密提取挑战平台
  • 构建本地化AI文本检测与人性化改写工具:从句子级高亮到精准干预
  • 仅限本周开放:ChatGPT产品描述生成诊断工具(实时解析你的Prompt缺陷并输出优化路径)
  • AI智能体工具库扩展:分层路由与动态编排架构设计实践
  • Keil µVision调试器中实现端口引脚互联的完整指南
  • 【ChatGPT面试通关黄金法则】:20年技术面试官亲授5大高频陷阱与3步反杀话术
  • 脉冲神经网络与神经形态计算的强化学习应用
  • 2026年 哈尔滨特种作业培训/特种设备安全管理/工业锅炉司炉/压力容器操作/气瓶充装/电梯修理/起重机指挥/司机/特种证件复审/实操培训推荐榜单 - 品牌企业推荐师(官方)
  • 从‘找不同’到‘学正常’:一文读懂工业异常检测的四大门派(附代码实战)
  • 从NTC到K型热电偶:我的STM32高温测量升级之路(附MAX6675完整代码)
  • 2026年深孔钻探厂家推荐榜单:矿产勘查/水利隧道/地热温泉/地质灾害钻探工程实力品牌解析 - 品牌企业推荐师(官方)
  • 如何在Windows 11上快速搭建安卓开发环境:WSA完整指南
  • 别再只当门禁卡用了!用ACR122U读写器+PN532芯片,手把手教你分析M1卡扇区数据(附实战案例)
  • 恢复 Windows 7 的经典照片查看器(Windows Photo Viewer)
  • 告别低效加班,ChatGPT帮你重写日程表:基于1762名知识工作者行为数据的时间优化模型
  • ChatGPT写抖音脚本总像“AI味”太重?5个反模板化指令+4类情绪锚点词库,让脚本开口即抓人
  • Dallas 390/400微控制器连续模式配置指南