#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() ,这样返回的是字符串副本而不是引用。
[]() -> { 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;
}