類 lambda 和捕獲這個

在類的成員函式中計算的 lambda 表示式隱式地是該類的朋友:

class Foo
{
private:
    int i;
    
public:
    Foo(int val) : i(val) {}
    
    // definition of a member function
    void Test()
    {
        auto lamb = [](Foo &foo, int val)
        {
            // modification of a private member variable
            foo.i = val;
        };
        
        // lamb is allowed to access a private member, because it is a friend of Foo
        lamb(*this, 30);
    }
};

這樣的 lambda 不僅是該類的朋友,它具有與其宣告的類相同的訪問許可權。

Lambdas 可以捕獲 this 指標,該指標表示呼叫外部函式的物件例項。這是通過將 this 新增到捕獲列表來完成的:

class Foo
{
private:
    int i;
    
public:
    Foo(int val) : i(val) {}
    
    void Test()
    {
        // capture the this pointer by value
        auto lamb = [this](int val)
        {
            i = val;
        };
        
        lamb(30);
    }
};

當捕獲 this 時,lambda 可以使用其包含類的成員名稱,就像它在其包含的類中一樣。所以隱含的 this-> 應用於這些成員。

請注意,this 是按值捕獲的,而不是型別的值。它由 this 的值捕獲,this 是一個指標。因此,lambda 不擁有 this。如果 lambda out 存在於建立它的物件的生命週期中,則 lambda 可能變為無效。

這也意味著 lambda 可以修改 this 而不會被宣告為 mutable。它是 const 的指標,而不是指向的物件。也就是說,除非外部成員函式本身就是一個 const 函式。

另外,請注意預設捕獲子句 [=][&] 將隱式捕獲 this。它們都通過指標的值捕獲它。實際上,當給出預設值時,在捕獲列表中指定 this 是錯誤的。

Version >= C++ 17

Lambdas 可以捕獲建立 lambda 時建立的 this 物件的副本。這是通過將*this 新增到捕獲列表來完成的:

class Foo
{
private:
    int i;
    
public:
    Foo(int val) : i(val) {}
    
    void Test()
    {
        // capture a copy of the object given by the this pointer
        auto lamb = [*this](int val) mutable
        {
            i = val;
        };
        
        lamb(30); // does not change this->i
    }
};