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