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

为何这些C++ Lambda会复制字符串并触发段错误?

std::function返回引用时的拷贝问题解析

先看测试代码:

#include <functional>
#include <iostream>
#include <string>

class Foo
{
public:
    const std::string& GetData() { return m_data; }
    std::string m_data = "foo data";
};

std::string s_data = "hello";
const std::string& GetData() { return s_data; }

int main()
{
    // Trial #1 - Seg faults.  String copied.
    //std::function<const std::string&()> getter1 = [] { return GetData(); };
    //std::cout << "data = " << getter1() << std::endl;

    // Trial #2 - Seg faults.  String copied.
    //auto* foo = new Foo();
    //std::function<const std::string&()> getter2 = [foo] { return foo->GetData(); };
    //std::cout << "data = " << getter2() << std::endl;
    //delete foo;

    // Trial #3 - Works
    auto getter3 = [] { return GetData(); };
    std::cout << "data = " << getter3() << std::endl;

    // Trial #4 - Works
    auto* foo2 = new Foo();
    auto getter4 = [foo2] { return foo2->GetData(); };
    std::cout << "data = " << getter4() << std::endl;
    delete foo2;

    return 0;
}

试验1、2触发段错误的核心原因

问题出在Lambda的返回类型推导规则上:

  • 虽然GetData()返回的是const std::string&,但Lambda默认会把返回类型推导成值类型std::string,这就会触发一次字符串拷贝,生成临时对象。
  • 当把这个Lambda赋值给std::function<const std::string&()>时,std::function会尝试返回临时对象的引用,但临时对象的生命周期只到Lambda执行结束。等后续调用getter1()或getter2()时,引用指向的对象已经销毁,直接触发段错误。

试验3、4正常运行的原因

用auto推导getter3和getter4的类型时,编译器会根据Lambda的实际返回类型(推导后的std::string)生成对应闭包类型。调用时返回的是拷贝后的字符串对象,这个对象的生命周期足够支撑到cout输出完成,所以不会出问题。你的猜测没错,这两个getter的实际返回类型确实是std::string,而非引用。

修复试验1、2的方法

显式指定Lambda的返回类型为引用,让它直接返回原对象的引用而非拷贝:

// 修复试验1
std::function<const std::string&()> getter1 = []() -> const std::string& { return GetData(); };
// 修复试验2(注意:要保证foo在getter2使用前不被销毁,原代码里delete foo后调用仍会出错)
auto* foo = new Foo();
std::function<const std::string&()> getter2 = [foo]() -> const std::string& { return foo->GetData(); };
std::cout << "data = " << getter2() << std::endl;
delete foo;

内容的提问来源于stack exchange,提问作者Josh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 20:41:24