我明白捕捉到正确的方法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
引用,因为它是一个小的常量指针。 你永远只能希望按值传递它-所以语言只是不支持拍摄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]在λ-表达的上下文中考虑。
所以拉姆达行为,如果它是包围部件功能的一部分(在你的例子一样使用名称的使用,当成员名称x
),所以它会产生的“隐性习惯” this
就像一个成员函数一样。
如果一个lambda捕获包括捕获,默认是&
在λ-捕获的标识不得由之前&
。 如果λ-捕获包括捕获默认即=
时,λ-捕获不得含有this
,并且它包含每个标识符应由前面&
。 标识符或this
不应出现一次以上的λ-捕获。
因此可以使用[this]
, [&]
, [=]
或[&,this]
作为lambda-introducer
以捕获this
由值指针。
然而[&this]
和[=, this]
是形成不良。 在最后一种情况GCC forgivingly警告为[=,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
对于拉姆达捕获的目的,表达可能引用本地实体如下:
7.3该表达式可能引用*此。
因此,标准保证this
和*this
是有效的,而&this
是无效的。 此外,捕获this
意味着捕捉*this
(这是一个左值,对象本身) 作为参考 , 而不是捕获this
通过值指针!