You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

按引用传递的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 14:36:06