[=]值拷贝局部变量,[&]引用绑定局部变量;二者均不捕获静态/全局变量及函数参数,且隐式捕获所有当前作用域可见的局部变量(含未使用变量)。

lambda 捕获列表里 [=] 和 [&] 到底绑定什么
它们不捕获“变量名”,而是捕获“当前作用域中可见的局部变量实体”。[=] 对每个变量做值拷贝(调用拷贝构造),[&] 对每个变量做引用绑定(不调用构造函数)。注意:静态局部变量、全局变量、函数参数(非局部)不会被自动捕获,哪怕名字出现在表达式里。
常见错误现象:[=] 捕获后修改 lambda 内部变量,不影响外部;[&] 捕获后外部变量提前销毁,lambda 调用时触发未定义行为(如访问悬空引用)。
-
[=]等价于显式写[a, b, c](对 a/b/c 值拷贝),但会隐式捕获所有局部变量——包括你没在 lambda 体里用到的 -
[&]同理隐式捕获所有局部变量的引用,同样包含未使用的变量 - 混合使用如
[&, a]表示“其余全引用捕获,但 a 单独值捕获”;[=, &b]表示“其余全值捕获,但 b 单独引用捕获”
std::function 存储引用捕获 lambda 可能出问题
当把引用捕获的 lambda 赋给 std::function 并离开原作用域后,闭包内部的引用大概率已失效。编译器不会报错,运行时行为不可预测(常见 crash 或读到垃圾值)。
典型场景:函数返回一个 std::function,内部 lambda 捕获了函数栈上的局部变量并用了 [&]。
立即学习“C++免费学习笔记(深入)”;
- 解决办法:改用值捕获(
[=]),或确保被引用对象生命周期 ≥ lambda 生命周期(例如捕获类成员时用this) - 若必须引用外部状态,考虑传入
std::shared_ptr并在 lambda 中捕获该智能指针(值捕获shared_ptr是安全的) - Clang/GCC 的
-Wdangling-gsl或 AddressSanitizer 可在部分情况下检测悬空引用,但不覆盖所有 case
mutable 关键字只对值捕获变量起作用
mutable 允许 lambda 修改其值捕获的副本,但它对引用捕获变量无效(引用本身不可变,但所指对象可变)。
例如:[x](int y) mutable { x += y; } 合法(x 是拷贝副本);[&x](int y) mutable { x += y; } 中 mutable 完全多余——引用捕获本就不限制修改所指对象。
- 值捕获 +
mutable:修改的是 lambda 自己的副本,不影响外部变量 - 引用捕获:修改直接作用于原变量,
mutable不影响语义,加了也没用 - const lambda(无
mutable)下,值捕获变量不可修改,引用捕获变量仍可修改(只要原变量非 const)
this 捕获在类成员函数里的实际含义
在非静态成员函数中,[this] 捕获的是当前对象的指针(不是对象副本),无论用 [=] 还是 [&],this 都是隐式按值捕获的指针。这意味着你可以通过 this->member 访问成员变量,但要注意:如果 lambda 在对象析构后被调用,this 就成了悬空指针。
-
[=]在类内会隐式包含[this],等价于[this](不拷贝整个对象) -
[&]在类内也隐式包含[this],仍是值捕获指针,不是引用捕获对象 - 想真正按值捕获整个对象,得显式写
[obj = *this](要求类可拷贝) - 捕获
[weak_this = weak_from_this()]是线程安全访问 shared_ptr 控制对象的常用模式










