2013-03-25 53 views
7

假设我有以下几点。Lambda表达式偷偷`捕获``

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; }; 
    } 
} 

现在我有以下代码。

auto a = std::make_shared<A>(); 
a->x = 5; 
std::function<int()> f = a.f#(); 
a.reset(); 
int x = f(); 

其中f#指的是任何的f1, f2, f3, f4, f5

这些功能在两套一个展示行为:

  1. 回报5称为(f5)时,或
  2. 坠毁试图取消引用nullptrf1, f2, f3, f4)。

据我所知,这是因为有些人正在隐式或显式地在成员函数A中捕获“this”。

确定行为1或2的正式规则是什么?

我花了一段时间处理,是由类似于f1东西造成的错误,以为它会捕捉x从不认为它会捕捉this,所以我想这将是获得这个文件非常有用。

回答

8

没有正式的规则来决定这种行为。因为这种行为是undefined

您的lambda正在访问一个不存在的对象。您无法直接通过值捕获成员变量;你总是通过this捕获它们。这意味着你通过引用捕获它们。一旦对象被删除,任何访问被删除对象的尝试都会导致未定义的行为。

这是一个例外f5,它应该返回一个确定的值。它与原始对象完全断开。

+0

噢 - 我把这两个组标记为'f1,f2,f3,f4'和'f5'!是的,我的意思是说'f5'能够正常工作,而其他人则不能。编辑。 – 2013-03-25 06:36:45