[英]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.