考虑一下:
#include <iostream> #include <functional> std::function<void()> task; int x = 42; struct Foo { int& x; void bar() { task = [=]() { std::cout << x << '\n'; }; } }; int main() { { Foo f{x}; f.bar(); } task(); }
我的直觉是,当执行任务时,实际的指示对象仍然存在,我们在遇到lambda时得到一个新绑定的引用,一切都很好.
但是,在我的GCC 4.8.5(CentOS 7)上,我看到一些行为(在更复杂的程序中)表明这是UB,因为f和参考f.x本身已经死亡.是对的吗?
解决方法
要捕获成员引用,您需要使用以下语法(在C 14中引入):
struct Foo { int & m_x; void bar() { task = [&l_x = this->m_x]() { std::cout << l_x << '\n'; }; } };
这样l_x就是一个int&存储在闭包中并引用m_x引用的相同int值,并且不受Foo超出范围的影响.
struct Foo { int & m_x; void bar() { int * p_x = &m_x; task = [=]() { std::cout << *p_x << '\n'; }; } };