C++中的lambda捕获列表[=]和[&]的区别?(值传递与引用传递的差异)
发布时间 - 2026-01-22 00:00:00 点击率:次值捕获[=]仅拷贝lambda体实际使用的自动变量值,不捕获this、静态/全局变量;引用捕获[&]以引用方式捕获使用变量,有生命周期风险;混合捕获可覆盖默认方式,[=, &x]表示x引用捕获其余值捕获。
捕获列表 [=] 是值捕获,但不等于“所有变量都拷贝”
使用 [=] 时,lambda 会以值方式捕获当前作用域中**被 lambda 体实际使用到的**自动变量(即 odr-used)。没被用到的变量不会被捕获,哪怕写了 [=]。它不会捕获 this(除非显式写 [=, this]),也不会捕获静态局部变量或全局变量(它们本就不需要捕获)。
注意:即使变量是引用类型(如 int& x = y;),[=] 捕获的仍是该引用所指向对象的**值副本**,不是原引用本身。
- 若捕获对象不可拷贝(如
std::unique_ptr),编译失败 - 若对象很大,可能带来不必要的拷贝开销
- 修改捕获后的变量,不影响原变量
捕获列表 [&] 是引用捕获,生命周期风险必须手动管理
[&] 以引用方式捕获所有被 lambda 体实际使用的自动变量。它同样不捕获未使用的变量,也不捕获 this 自动(需显式加 [&, this])。
关键问题是:如果 lambda 在定义它的作用域结束后仍被调用(比如返回后存储、异步执行),而它引用的变量已经销毁,行为就是未定义的——常见 crash 或读脏内存。
- 捕获的是变量本身的引用,修改 lambda 内部的
x就等于修改原变量 - 对只读场景更轻量(无拷贝),但极易误用
- 不能捕获临时对象(如函数返回的右值),因为其生命周期通常短于 lambda
混合捕获 [=, &x] 和 [=, x] 的行为差异
C++ 允许混合捕获,但规则严格:一旦用了 [=] 或 [&],其余显式捕获必须与之“方向一致”,除非显式覆盖。例如:
int a = 1, b = 2;
auto f1 = [=, &a]() { a++; b++; }; // 合法:a 引用捕获,b 值捕获
auto f2 = [&a, b]() { a++; b++; }; // 合法:a 引用,b 值
auto f3 = [=, b]() { 
}; // 错误:重复指定 b 的捕获方式
特别注意:[=, &x] 中的 &x 是对默认值捕获的**覆盖**,不是追加;而 [&, x] 中的 x 是对默认引用捕获的覆盖(此时 x 是值捕获)。
-
[=, &x]:绝大多数变量值捕获,仅x引用捕获 -
[&, x]:绝大多数变量引用捕获,仅x值捕获 - 不能混用
[=, x](x已被=覆盖,再写是重复)
捕获 this 的隐含规则和陷阱
在类成员函数中,[=] 和 [&] 都**不会自动捕获 this 指针**。这意味着 lambda 无法访问 this->member,除非你显式写 [=, this] 或 [&, this]。
更隐蔽的问题是:即使你写了 [=],它也只捕获 this 指针的值(即对象地址),而不是对象本身;所以你可以安全调用成员函数(只要对象还活着),但不能假设对象数据没被析构。
- 在异步回调中,
[=, this]很常见,但务必确保对象生命周期长于 lambda 执行期 - 用
shared_from_this()配合std::shared_ptr是更安全的替代方案 -
[this](无 = 或 &)等价于[=, this],C++17 起允许
# c++
# 区别
# 作用域
# red
# 成员函数
# 局部变量
# 全局变量
# int
# Lambda
# 指针
# 引用类型
# 值传递
# 引用传递
# 闭包
# 对象
# this
# 异步
# 问题是
# 写了
# 的是
# 也不
# 变量值
# 你可以
# 就不
# 已被
# 用了
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Laravel如何与Docker(Sail)协同开发?(环境搭建教程)
高端建站三要素:定制模板、企业官网与响应式设计优化
Laravel如何实现事件和监听器?(Event & Listener实战)
如何在搬瓦工VPS快速搭建网站?
Laravel Blade组件怎么用_Laravel可复用视图组件的创建与使用
Laravel的契約(Contracts)是什么_深入理解Laravel Contracts与依赖倒置
如何用已有域名快速搭建网站?
如何在VPS电脑上快速搭建网站?
laravel怎么用DB facade执行原生SQL查询_laravel DB facade原生SQL执行方法
Laravel如何生成PDF或Excel文件_Laravel文档导出工具与使用教程
独立制作一个网站多少钱,建立网站需要花多少钱?
如何用AI一键生成爆款短视频文案?小红书AI文案写作指令【教程】
如何快速查询域名建站关键信息?
Laravel如何升级到最新的版本_Laravel版本升级流程与兼容性处理
晋江文学城电脑版官网 晋江文学城网页版直接进入
Laravel如何实现API速率限制?(Rate Limiting教程)
详解jQuery中的事件
标题:Vue + Vuex 项目中正确使用 JWT 进行身份认证的实践指南
Laravel如何实现一对一模型关联?(Eloquent示例)
如何快速搭建高效WAP手机网站吸引移动用户?
Linux后台任务运行方法_nohup与&使用技巧【技巧】
Laravel项目如何进行性能优化_Laravel应用性能分析与优化技巧大全
Laravel怎么实现搜索高亮功能_Laravel结合Scout与Algolia全文检索【实战】
jQuery中的100个技巧汇总
音乐网站服务器如何优化API响应速度?
如何制作一个表白网站视频,关于勇敢表白的小标题?
魔方云NAT建站如何实现端口转发?
Win11怎么关闭透明效果_Windows11辅助功能视觉效果设置
公司门户网站制作流程,华为官网怎么做?
Win11怎么关闭专注助手 Win11关闭免打扰模式设置【操作】
详解Nginx + Tomcat 反向代理 负载均衡 集群 部署指南
Laravel Octane如何提升性能_使用Laravel Octane加速你的应用
Laravel Eloquent性能优化技巧_Laravel N+1查询问题解决
零服务器AI建站解决方案:快速部署与云端平台低成本实践
个人摄影网站制作流程,摄影爱好者都去什么网站?
如何在阿里云服务器自主搭建网站?
Windows11怎样设置电源计划_Windows11电源计划调整攻略【指南】
怎么制作一个起泡网,水泡粪全漏粪育肥舍冬季氨气超过25ppm,可以有哪些措施降低舍内氨气水平?
Laravel Vite是做什么的_Laravel前端资源打包工具Vite配置与使用
Laravel中的Facade(门面)到底是什么原理
深圳网站制作培训,深圳哪些招聘网站比较好?
实现点击下箭头变上箭头来回切换的两种方法【推荐】
Win11怎么开启自动HDR画质_Windows11显示设置HDR选项
Laravel Artisan命令怎么自定义_创建自己的Laravel命令行工具完全指南
Laravel怎么创建控制器Controller_Laravel路由绑定与控制器逻辑编写【指南】
高防服务器租用指南:配置选择与快速部署攻略
Java Adapter 适配器模式(类适配器,对象适配器)优缺点对比
Laravel Telescope怎么调试_使用Laravel Telescope进行应用监控与调试
北京网站制作公司哪家好一点,北京租房网站有哪些?
Laravel怎么使用artisan命令缓存配置和视图


