为什么我无法在 lambda 中捕获此副引用("&this")?
Why can't I capture this by-reference ('&this') in lambda?
我理解在lambda中捕获this
(修改对象属性)的正确方法如下:
auto f = [this] () { /* ... */ };
但是我对我所看到的以下特点很好奇:
class C {
public:
void foo() {
// auto f = [] () { // this not captured
auto f = [&] () { // why does this work?
// auto f = [&this] () { // Expected ',' before 'this'
// auto f = [this] () { // works as expected
x = 5;
};
f();
}
private:
int x;
};
奇怪的是,我感到困惑(并希望回答)是为什么以下工作:
auto f = [&] () { /* ... */ }; // capture everything by reference
以及为什么我不能通过引用显式捕获this
:
auto f = [&this] () { /* ... */ }; // a compiler error as seen above.
[&this]
不工作的原因是因为它是语法错误。lambda-introducer
中每个以逗号分隔的参数都是一个capture
:
capture:
identifier
& identifier
this
你可以看到&this
在语法上是不允许的。不允许这样做的原因是,您永远不想通过引用捕获this
,因为它是一个小的const指针。您可能只希望通过值传递它-因此语言不支持通过引用捕获this
。
要显式捕获this
,您可以使用[this]
作为lambda-introducer
。
第一个capture
可以是capture-default
,即
capture-default:
&
=
这意味着自动捕获我使用的任何内容,分别通过引用(&
)或值(=
) -然而this
的处理是特殊的-在这两种情况下,它都是根据前面给出的原因按值捕获(即使默认捕获&
,这通常意味着通过引用捕获)。
5.1.2.7/8:
用于名称查找(3.4),确定
this
(9.3.2)的类型和值并转换id-使用(*this)
(9.3.1)将引用非静态类成员的表达式转换为类成员访问表达式,复合语句[OF the LAMBDA]在LAMBDA表达式的上下文中被考虑。
因此,当使用成员名时,lambda就像它是封闭成员函数的一部分一样(就像在您的示例中使用名称x
一样),因此它将像成员函数一样生成this
的"隐式用法"。
如果lambda-capture包含一个默认的capture-default为
&
,则lambda-capture中的标识符不能为前面是&
。如果lambda-capture包含默认捕获值=
,则lambda-capture不包含this
和它所包含的每一个标识符之前都必须有&
。标识符或this
不能出现超过
因此,您可以使用[this]
, [&]
, [=]
或[&,this]
作为lambda-introducer
来按值捕获this
指针。
然而[&this]
和[=, this]
是病态的。在最后一种情况下,gcc宽容地警告[=,this]
, explicit by-copy capture of ‘this’ redundant with by-copy capture default
而不是错误。
因为标准在捕获列表中没有&this
:
N4713 8.4.5.2捕获:
lambda-capture:
capture-default
capture-list
capture-default, capture-list
capture-default:
&
=
capture-list:
capture...opt
capture-list, capture...opt
capture:
simple-capture
init-capture
simple-capture:
identifier
&identifier
this
* this
init-capture:
identifier initializer
&identifier initializer
对于lambda捕获的目的,表达式可能引用本地实体如下:
7.3 A this表达式可能引用*this。
因此,标准保证this
和*this
有效,&this
无效。另外,捕获this
意味着通过引用捕获*this
(它是一个左值,对象本身),而不是通过值捕获this
指针 !
- 为什么我需要在转换构造函数上引用 this->?
- 为什么在通过引用返回运算符分配时取消引用'this'指针?
- QPointer::clear() 是删除其引用的指针,还是"Clears this QPointer object."其他含义?
- 使用 decltype(this) 获取函数引用
- 当取消引用运算符 (*) 重载时,*this 的使用是否受到影响?
- 难道不应该有一个类似于"this"的与名称无关的类指针供成员函数在C++中引用吗?
- 通过在引用线程对象来传递取消引用的“this”指针来在函数对象构造函数中创建线程是好是坏
- 返回 *this,尝试级联,并且不返回引用
- 为什么有些类方法返回"*this"(self的对象引用)?
- G++ 4.9.2 传递引用'this'时的回归
- 使用"this ->"引用类的成员是否有好处或性能提升?
- C++ 通过引用将“this”传递到方法中
- 返回对"this"的取消引用的重写方法
- 如果参数采用引用,在函数参数中传递 *this 会导致内存泄漏
- C++如何将'this'传递给指针引用
- 为什么 fstream 方法返回对"*this"的引用?
- 错误 C2355:'this':只能在非静态成员函数或非静态数据成员初始值设定项中引用
- 什么时候应该使用指针或引用成员,什么时候应该在Qt中传递nullptr或this作为父指针
- 是否允许将 *this 作为接受引用(&)的函数的参数传递?
- 为什么我无法在 lambda 中捕获此副引用("&this")?