必须用[this]而非[=]或[&]访问类成员,因后两者不捕获this指针;C++17起可用[*this]按值拷贝对象;空捕获[]最安全,避免生命周期问题。

Lambda 捕获 this 时为什么不能直接用 [=] 或 [&] 访问成员变量?
因为 [=] 捕获的是当前作用域的局部变量(不含 this),[&] 同理——它不自动绑定 this,所以无法访问 member_var 或调用 member_func()。C++11 起,Lambda 默认不隐式捕获 this,哪怕你在类成员函数里写 Lambda,也得显式告诉编译器“我要用当前对象”。
正确做法是显式捕获 this:[this],或用 [=, this](C++17 起允许混合值捕获与 this)。
-
[this]:只捕获this指针,所有成员通过this->x访问(推荐,语义清晰) -
[=, this]:值捕获所有局部变量 + 显式捕获this(C++17+) -
[&]在成员函数中仍不包含this,所以member_var会报错 —— 编译器不认为它是“局部变量”
用 [this] 替代 std::bind(&Class::func, this, _1) 的实操写法
以前用 std::bind 绑定成员函数,本质是把 this 和参数打包成可调用对象;现在 Lambda 更直接、无类型擦除开销,且支持完美转发。
比如原写法:
立即学习“C++免费学习笔记(深入)”;
auto bound = std::bind(&MyClass::process, this, std::placeholders::_1);
等价的 Lambda 是:
auto lambda = [this](int x) { return process(x); };
- 没有
std::placeholders、不用记下划线编号,参数列表直写 - 返回类型自动推导(也可显式写
-> void或-> int) - 如果
process是 const 成员函数,Lambda 需加const限定:[this](int x) const { ... } - 若需转发参数(如模板函数或万能引用),用
auto&&+std::forward,std::bind做不到这点
捕获成员变量 vs 捕获 this:什么时候该用 [member_var]?
直接捕获成员变量(如 [member_var])是按值拷贝一份,和 this 无关——它捕获的是表达式 member_var 当前的值,不是“对成员的引用”。这在多数场景下是陷阱。
- ✅ 正确场景:你明确想快照某个成员的**瞬时值**(比如启动异步任务时记录日志 ID)
- ❌ 错误场景:想在 Lambda 里读/写当前对象的成员状态(此时应
[this],否则修改的是副本) - ⚠️ 特别注意:
[member_var]不等于[&member_var];后者非法——成员变量不能直接取引用捕获,必须通过this访问
Lambda 替代 std::bind 后的生命周期风险更隐蔽
std::bind 对象如果持有 this,和 Lambda 一样面临悬垂指针问题:对象销毁后,Lambda 还被调用就会崩溃。但 Lambda 的捕获语法太简洁,反而让人忽略这个前提。
- 用
[this]的 Lambda 必须确保:调用它时,this所指对象仍然存活 - 若 Lambda 可能逃逸出当前作用域(如传给异步 API、存入容器),请确认对象生命周期足够长,或改用
std::shared_ptr<this_type></this_type>+[weak_this = weak_from_this()]安全检查 - 编译器不会警告
[this]悬垂,而std::bind至少还带点“我在绑东西”的心理提示
最易被忽略的点:Lambda 捕获 this 后,看起来像普通闭包,容易当成纯函数用,忘了它本质是个带状态的对象指针。


















