簡體   English   中英

c ++ lambda按值捕獲

[英]c++ lambda capture by value

我正在閱讀本書第3章中的C ++ lambda部分,以下代碼讓我困惑:

int x = 0;
int y = 42;
auto qqq = [x, &y] {
    std::cout << "x: " << x << std::endl;
    std::cout << "y: " << y << std::endl;
    ++y;
};
x = y = 77;
qqq();
qqq();
std::cout << "final y: " << y << std::endl;

這段代碼打印出來:

x: 0
y: 77
x: 0
y: 78
final y: 79

為什么qqq()沒有注冊x已經改為77? 據說,通過值傳遞意味着我們可以讀取但不能修改定義lambda的數據。 這是否意味着我們在定義后無法看到變化?

這是因為當你定義lambda時,變量只被值(即復制)捕獲一次。 它可能不會像您所認為的那樣“更新”。 代碼大致相當於:

#include <iostream>

int x = 0;
struct Lambda
{
    int _internal_x; // this is used to "capture" x ONLY ONCE
    Lambda(): _internal_x(x) {} // we "capture" it at construction, no updates after
    void operator()() const
    {
        std::cout << _internal_x << std::endl;
    }
} qqq; 

int main()
{
    qqq(); 
    x = 77; // this has no effect on the internal state of the lambda
    qqq();
}

住在Coliru

通過將值變量綁定到lambda閉包,您可以有效地將變量的值復制到lambda對象中的單獨變量中。 同樣,通過引用綁定變量,您將使這樣的內部變量成為對原始變量的引用,從而能夠“看到原始變量的變化”。

像這樣看待它。 以下代碼......

#include <iostream>

int main()
{
    int x = 0;
    int y = 42;
    auto qqq = [x, &y] {
        std::cout << "x: " << x << std::endl;
        std::cout << "y: " << y << std::endl;
        ++y;
    };
    x = y = 77;
    qqq();
    qqq();
    std::cout << "final y: " << y << std::endl;
}

是(種類,但不完全)語法糖...

#include <iostream>

class MyLambda
{
    private:
        int x;
        int& y;

    public:
        MyLambda(int x, int& y) : x(x), y(y) {}

        void operator()()
        {
            std::cout << "x: " << x << std::endl;
            std::cout << "y: " << y << std::endl;
            ++y;
        }
};

int main()
{
    int x = 0;
    int y = 42;
    MyLambda qqq = MyLambda(x, y);
    x = y = 77;
    qqq();
    qqq();
    std::cout << "final y: " << y << std::endl;
}

除了特殊的lambda語法和你不能直接引用lambda類型的事實。 通過將前者與后面的代碼進行比較,您應該能夠清除對閉包的理解。

lambda使用lambda定義時的值(它創建一個副本),而不是在調用它時。

這可能有所幫助: Lambda Closures如何實現?

暫無
暫無

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

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