为什么我不能在lambda中捕获这个引用('&this')?
我理解在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
是不允许的语法。 它不被允许的原因是因为你永远不会想要通过引用来捕获它,因为它是一个小的const指针。 你只会想要传递它的价值 – 所以语言不支持通过引用来捕获。
要明确地捕获this
你可以使用[this]
作为lambda-introducer
。
第一个capture
可以是一个capture-default
是:
capture-default: & =
这意味着分别通过引用( &
)或值( =
)自动捕获任何我使用的内容 – 但是这种处理是特殊的 – 在这两种情况下,由于前面给出的原因(通过默认捕获&
,通常意味着通过引用捕获)。
5.1.2.7/8:
为了查找名称(3.4),确定
this
(9.3.2)的types和值,并使用(*this)
(9.3.1)将涉及非静态类成员的id-expression式转换为类成员访问expression式, lambdaexpression式的复合语句被认为是在lambdaexpression式的上下文中。
所以当使用成员名称(就像在你的例子中使用名称x
)时,lambdaperformance得好像是包含成员函数的一部分,所以它会像成员函数一样产生“隐式用法”。
如果一个lambda捕获包括一个捕获默认值是
&
,lambda捕获中的标识符不应该在&
之前。 如果一个lambda捕获包含一个=
的捕获缺省值,那么lambda捕获不包含this
并且它包含的每个标识符都应该以&
为前缀。 一个标识符或者this
在lambda-capture中不能出现一次以上。
所以你可以使用[this]
, [&]
, [=]
或[&,this]
作为lambda-introducer
来按值捕获this
指针。
然而[&this]
和[=, this]
是不合格的。 在最后一种情况下,gcc谨慎地警告[=,this]
explicit by-copy capture of 'this' redundant with by-copy capture default
而不是错误。