簡體   English   中英

Lambda變量捕獲

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

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