[英]Lambda variable capture
我對lambda表達式的變量捕獲部分的性質感到困惑。
void f1();
std::function<int()> f2;
int main() {
f1();
std::cout<<f2()<<endl;
}
void f1() {
int x;
f2 = [&]() {
return x;
};
}
在調用f2
之前x
不會被解構嗎?
是。 您已成功調用未定義的行為。 一種可能的結果是您得到x的值。 另一個原因是計算機格式化了硬盤驅動器,程序崩潰或計算機變成了自動烘烤面包機的刺客,為您提供蛋糕,錯誤地認為您患有乳糜瀉。
一個安全的變體可能是:
int main() {
f1(7);
std::cout<<f2()<<endl;
}
void f1(int x) {
std::shared_ptr<int> spX( new int(x) );
f2 = [=]() {
return *spX;
};
}
要么
void f1(int x) {
f2 = [=]() {
return x;
};
}
(對於int,沒有理由不按值存儲它:對於更復雜的類型,您可能要避免不必要地對其進行復制)。
請注意,上面的注釋以更有趣的方式說明了這一點。
現在,當您遞減堆棧以恰好捕獲這種未定義的行為時,某些編譯器將使用特殊值標記堆棧(通過catch,我的意思是使堆棧對程序員更明顯)。 但是在大多數情況下,可以在C ++中調用未定義的行為。
在調用f2之前x不會被解構嗎?
是的。 這意味着return x
評估一個懸空引用,該引用引用了未定義的行為。
在這種情況下,您可能更喜歡按值捕獲。
f2 = [x]() { return x; }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.