假设我有以下内容.
struct A
{
int x;
std::function<int()> f1() { return [=](){ return x; }; }
std::function<int()> f2() { return [=](){ return this->x; }; }
std::function<int()> f3() { return [this](){ return x; }; }
std::function<int()> f4() { return [this](){ return this->x; }; }
std::function<int()> f5()
{
int temp = x;
return [=](){ return temp; };
}
}
Run Code Online (Sandbox Code Playgroud)
现在我有以下代码.
auto a = std::make_shared<A>();
a->x = 5;
std::function<int()> f = a.f#();
a.reset();
int x = f();
Run Code Online (Sandbox Code Playgroud)
在哪里f#
指的是任何一个f1, f2, f3, f4, f5
.
这些函数在两组中的一组中表现出行为:
f5
)时返回5 ,或nullptr
(f1, f2, f3, f4
).我理解这是因为有些人this
在A
隐式或显式的成员函数中捕获" " .
确定行为1或2的正式规则是什么?
我花了一段时间来处理由类似的东西引起的错误f1
,认为它会捕获x
并且从不考虑它会捕获this
,所以我认为记录它会很有用.
没有正式规则可以确定此行为.因为此行为未定义.
你的lambda正在访问一个不存在的对象.您无法直接按值捕获成员变量; 你总是抓住它们this
.这意味着您通过引用捕获它们.删除对象后,任何访问该已删除对象的尝试都会导致未定义的行为.
例外情况是f5
,应保证返回一致的值.它与原始对象完全断开连接.