Lambda捕获与生命周期陷阱
请分析Lambda表达式在使用中常见的陷阱,包括悬空引用、this指针捕获的隐患、返回值类型推导问题,以及如何安全地在Lambda中使用异步或延迟执行。
回答
小字辈
1.悬空引用:
auto f = [&]() { return a + b; }; // 若a,b是局部变量,函数返回后引用悬挂
解决:值捕获或确保Lambda生命周期不超过被捕获的引用。
2.this指针陷阱:
struct A {
int x = 10;
auto getLambda() { return [this](){ return x; }; } // 捕获this指针
};
// 若A对象销毁后调用Lambda,this悬空
解决:C++17可用[*this]值捕获整个对象,或确保Lambda不超出对象生命周期。
3.异步/延迟执行:
- 线程中使用的Lambda,确保捕获的对象在线程执行期间有效。
- 推荐使用值捕获智能指针:
[ptr = shared_from_this()](){}
4.返回值推导:
- 单条return语句自动推导类型。
- 多条return语句类型需一致,否则需显式指定返回类型。
5.静态变量捕获:Lambda不能直接捕获全局或静态变量,但可以直接访问(不需要捕获)。
最佳实践:尽量值捕获基本类型;引用捕获需要保证生命周期;对于类成员对象用[this]或[*this];在线程/回调中用智能指针。