为什么这些 C++ lambda 会复制字符串和段错误?

问题描述 投票:0回答:1
#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 string&。副本可能会在使用对其的引用之前被破坏 - 导致段错误。但是,我根本不明白为什么要复制。

试验 3 和 4 有效。我猜测 getter3 和 getter4 是 std::functionstd::string() ,这样返回的是字符串副本而不是引用。

c++ lambda
1个回答
0
投票

[]() -> { return GetData(); }
[]() -> { return GetData(); }
并且
auto
被推导为
std::string
。你的代码是 相当于

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

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

const std::string lambda() {
  return GetData();
}

const std::string& getter1() {
  return lambda();  // warning: returning reference to local temporary object [-Wreturn-stack-address]
}

int main() {
  std::cout << "data = " << getter1() << std::endl;
  return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.