類 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
}
};