按引用传递的Lambda在构造函数中可执行,存储为成员后失效
为什么存储的Lambda调用会崩溃?
这段C++代码执行时会先打印11.1,随后崩溃。构造函数内调用传入的Lambda正常,但后续调用存储的函数就失效了,这是为什么?Lambda存在生命周期限制吗?
#include <functional> #include <iostream> class LambdaStore { public: LambdaStore(const std::function<void(float)>& _fn) : fn(_fn) { fn(11.1f); // 正常执行 } void ExecuteStoredLambda() { fn(99.9f); // 崩溃 } private: const std::function<void(float)>& fn; }; int main() { LambdaStore lambdaStore([](float a) { std::cout << a << '\n'; }); lambdaStore.ExecuteStoredLambda(); }
问题原因
- 核心错误是类成员存储的是
std::function的引用,而非对象本身。 - 在
main函数中,你直接传递Lambda表达式给构造函数,编译器会自动将其转换为一个临时的std::function<void(float)>对象。 - C++中临时对象的生命周期仅持续到当前完整表达式结束,也就是构造函数执行完毕后,这个临时
std::function就会被销毁。 - 构造函数内调用
fn时,临时对象仍处于生命周期内,所以能正常执行;但调用ExecuteStoredLambda时,fn引用的是已经销毁的对象,属于悬空引用,触发未定义行为,最终表现为崩溃。 - 注意:Lambda本身的生命周期没有问题,崩溃的根源是你错误地存储了临时
std::function的引用,和Lambda自身无关。
解决方法
把类中的成员变量从引用类型改为值类型,直接存储std::function对象,这样构造函数会将临时对象拷贝(或移动)到成员变量中,确保后续调用时对象依然有效:
#include <functional> #include <iostream> class LambdaStore { public: LambdaStore(const std::function<void(float)>& _fn) : fn(_fn) { fn(11.1f); // 正常执行 } // 可选:添加移动构造函数优化性能 LambdaStore(std::function<void(float)>&& _fn) : fn(std::move(_fn)) { fn(11.1f); } void ExecuteStoredLambda() { fn(99.9f); // 正常执行 } private: std::function<void(float)> fn; // 去掉引用修饰 }; int main() { LambdaStore lambdaStore([](float a) { std::cout << a << '\n'; }); lambdaStore.ExecuteStoredLambda(); }
内容的提问来源于stack exchange,提问作者Rocketmagnet
相关产品推荐
相关产品推荐

