簡體   English   中英

C ++ Lambda:良好參考與不良參考

[英]C++ lambda: good reference vs. bad reference

我正在觀看CppCon 2015的視頻:為什么按價值捕獲好而按引用捕獲不好。

在此處輸入圖片說明

Arthur解釋了,但我不明白。。。Arthur說一個錯誤的引用是指一個局部變量然后退出,但是退出后堆棧應該清理並且局部變量消失了,那又是什么問題呢?

BAD_increment_by返回一個閉包,其中包含對y的引用,但是當該函數返回時y超出范圍,因此它包含一個懸空引用。 任何試圖調用該閉包的行為都是未定義的行為。

出於以下原因,這很糟糕:

int& BAD_copy(int x) { return x; }

不好。

我想嘗試以另一種方式解釋@Barry的回答。

讓我們寫下BAD_increment_by內部發生的事情。

  1. 有一個局部變量y
  2. 拉姆達捕獲y引用。 這將創建一個稱為y的引用。 好吧,它們恰好具有相同的名稱,這令人困惑...讓我們將第一個稱為“值y ”,將第二個稱為“引用y ”。
  3. lambda的主體使用參考y
  4. Lambda由BAD_increment_by返回。

BAD_increment_by返回BAD_increment_by

  1. y不再存在。
  2. 參考y仍指向值y ...
  3. 等待! y不存在! 參考y指向不存在的東西!

當有人調用lambda時,

  1. 讀取參考y
  2. 由於引用y是引用,因此我們將重定向到值y
  3. Errr ......難道真的看重y或者只是我的幻覺?

結論是:調用lambda時,將使用懸掛的引用。 該行為是不確定的。

您可以將lambda視為定義了operator()的類的簡寫,以便可以將其視為函數。

auto BAD_increment_by(int y)
{
    return [&](int x){return x+y;};
}

可以視為以下方面的簡寫:

struct BadClosure
{
    int&   y;
    BadClosure(int& y) // y is the only variable in scope
        : y(y)         // So the `&` only captures 'y'
    {}
    auto operator()(int x){return x+y;}
};
auto BAD_increment_by(int y)
{
    return BadClosure(y);
}

因此,如果我使用以上內容:

int main()
{
     // This object now has a reference to 
     // parameter 'y' from the function `BAD_increment_by()`
     //
     // But this function has exited.
     // So the reference held by this object is no longer
     // valid (ie it is a dangling reference).
     auto addTwo = BAD_increment_by(2);


     // Now use it
     // Internally this access the member y
     // which is a reference to the parameter 'y'
     // from a function that is no longer executing.
     std::cout << addTwo(5) << "\n";
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM