2013-03-25 59 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