簡體   English   中英

C ++ 11 lambda按值捕獲在聲明點捕獲

[英]C++11 lambda capture by value captures at declaration point

下面的代碼打印0,但我希望看到1.我的結論是lambda函數不是通過實際將捕獲的參數傳遞給函數來調用的,這更直觀。 我是對的還是我錯過了什么?

#include <iostream>
int main(int argc, char **argv){
  int value = 0;
  auto incr_value  = [&value]() { value++; };
  auto print_value = [ value]() { std::cout << value << std::endl; };
  incr_value();
  print_value();
  return 0;
}

通過將捕獲的參數實際傳遞給函數調用Lambda函數。

value是在其中的λ被定義(與點等於0 value被捕獲)。 由於您是按值捕獲的,因此捕獲后您的操作value無關緊要。

如果您通過引用捕獲了value ,那么您將看到1打印,因為即使捕獲點仍然相同(lambda定義),您將打印捕獲對象的當前值,而不是它創建時的副本它被捕獲了。

是的,捕獲是在聲明lambda的時候完成的,而不是在它被調用的時候完成的。 將lambda視為一個函數對象,其構造函數將捕獲的變量作為參數並將它們分配給相應的成員變量(值或引用,具體取決於捕獲模式。)lambda的實際調用沒有魔法,它只是一個常規operator()調用底層函數對象。

在調用點捕獲事物沒有多大意義 - 如果將lambda作為參數返回或傳遞給另一個函數並在那里調用,會捕獲什么? 實際上有一些語言會以這種方式運行 - 如果在函數中引用變量x ,則假定它在調用時引用當前在范圍內的任何名為x變量。 這稱為動態范圍。 大多數語言使用的替代方法,因為它使程序的推理更簡單,稱為詞法范圍。

http://en.wikipedia.org/wiki/Lexical_scoping#Lexical_scoping_and_dynamic_scoping

問題是您的打印功能是按值而不是通過引用捕獲的。

#include <iostream>
int main(int argc, char **argv){
  int value = 0;
  auto incr_value  = [&value]() { value++; };
  auto print_value = [ value]() { std::cout << value << std::endl; };
  auto print_valueref = [ &value]() { std::cout << value << std::endl; };

  incr_value();
  print_value();
  print_valueref();
  return 0;
}

按預期輸出0和1。 第一個是按值捕獲並在捕獲點打印值; 第二個捕獲引用,然后打印其值。

暫無
暫無

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

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