C++中lambda表达式怎么写_C++匿名函数捕获列表详解【现代】-C++

C++ lambda表达式必须符合“捕获列表->返回类型{函数体}”结构,捕获列表不可省略,返回类型可推导但多语句或类型不一致时需显式声明;五种捕获方式影响变量修改权、生命周期和悬垂引用;类内需显式捕获this访问成员;mutable允许修改值捕获副本;C++14支持初始化捕获实现移动语义。

lambda表达式基本写法:从语法结构开始

C++ lambda 不是“写出来就能用”,必须符合 capture -> return_type { body } 这个骨架。省略部分有严格规则:返回类型可推导时能省略 -> return_type,但一旦函数体含多条语句或含 return 表达式类型不一致,编译器就可能推导失败,报错如 error: no viable conversion from 'lambda' to 'std::function'。

  • 捕获列表 [...] 必须存在(哪怕为空 []),不能省略
  • 参数列表 (...) 为空时可写成 () 或直接省略(仅当无参且无返回类型声明时)
  • 若 lambda 需被赋给 std::function 或作为参数传入模板函数,建议显式写 -> 返回类型,避免因推导差异导致模板实例化失败

捕获列表的五种写法及实际影响

捕获方式决定 lambda 能否修改变量、能否跨作用域存活、以及是否引发悬垂引用——不是语法糖,是内存模型问题。

  • [x]:值捕获,复制一份 x。若 x 是大对象,注意拷贝开销;捕获后无法通过 lambda 修改外部 x
  • [&x]:引用捕获,不复制,但要求 x 的生命周期必须长于 lambda 本身,否则调用时触发未定义行为
  • [=]:默认值捕获,自动把当前作用域所有自动变量以值方式捕获。注意:不会捕获 this(类成员函数中需显式写 [this] 或 [=, this])
  • [&]:默认引用捕获,危险操作。一旦 lambda 在原作用域结束后被调用(比如存入容器、异步执行),几乎必然崩溃
  • [x, &y]:混合捕获,允许对不同变量用不同方式。但 C++17 起禁止 [x, x] 或 [&x, x] 这类重复/冲突写法,编译直接报错

在类成员函数里用 lambda 访问 this 和成员变量

类内写 lambda 时,this 不会自动捕获,更不会自动解引用。常见错误是以为 [=] 就能用 member_var,其实它只捕获局部变量,不包含隐式 this。

  • 想访问非静态成员,必须显式捕获 this:[this]() { return member_var; }
  • 若只需读取 const 成员,可用 [*this](C++17)做值捕获,此时 lambda 拥有当前对象的一份副本,后续即使原对象析构也不影响它
  • 捕获 this 后,仍要通过 this-> 或直接写成员名访问(编译器允许省略 this->,但逻辑上仍是通过指针访问)

移动捕获与 mutable:让 lambda 修改捕获的值

默认情况下,lambda 的函数调用运算符是 const 成员函数,所以即使值捕获了变量,也不能在 body 中给它赋值。

夏夕资源网专注于CMS网站模板,主流语言整站网站源码下载,网站建设相关教程分享,好用的软件素材整合下载,提供一站式便捷自助服务。
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,默认解压密码为"zy.lucklyus.top",如遇到无法解压的请联系管理员!
夏夕资源网-网站模板_免费源码_资源素材 » C++中lambda表达式怎么写_C++匿名函数捕获列表详解【现代】-C++
在线时间:12:00 - 22:00
关注微信公众号:微信公众号
站长邮箱:[email protected]
  • 运营天数: 1393+
  • 资源总数: 47989+
  • 用户总数: 1+
  • 今日更新: 0+
  • 访问次数: 4027074+
  • 本周更新: 0+
  • 最后更新: 2026-03-16

本站指数

×
  • 运营天数: 1393+
  • 资源总数: 47989+
  • 用户总数: 1+
  • 今日更新: 0+
  • 访问次数: 4027074+
  • 本周更新: 0+
  • 最后更新: 2026-03-16