我理解this
在lambda中捕获(修改对象属性)的正确方法如下:
auto f = [this] () { /* ... */ };
Run Code Online (Sandbox Code Playgroud)
但我很好奇我所看到的以下特点:
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;
};
Run Code Online (Sandbox Code Playgroud)
我很困惑的奇怪(并希望得到回答)是以下工作的原因:
auto f = [&] () { /* ... */ }; // capture everything by reference
Run Code Online (Sandbox Code Playgroud)
为什么我不能通过this
引用明确捕获:
auto f = [&this] () { /* ... */ }; // a compiler error as seen above.
Run Code Online (Sandbox Code Playgroud)
And*_*zos 100
原因[&this]
不起作用是因为它是语法错误.每个逗号分隔的参数lambda-introducer
是capture
:
capture:
identifier
& identifier
this
Run Code Online (Sandbox Code Playgroud)
你可以看到&this
语法上不允许这样做.它不被允许的原因是因为this
它是一个小的const指针,你永远不想通过引用捕获它.您只希望按值传递它 - 因此语言不支持this
通过引用捕获.
要捕获this
明确可以使用[this]
的lambda-introducer
.
第一个capture
可以capture-default
是:
capture-default:
&
=
Run Code Online (Sandbox Code Playgroud)
这意味着分别通过引用(&
)或值(=
)分别自动捕获我使用的任何东西- 但是处理this
是特殊的 - 在两种情况下都是由于前面给出的原因而被值捕获(即使是默认捕获&
,这通常意味着通过引用捕获).
5.1.2.7/8:
出于名称查找(3.4)的目的,确定
this
(9.3.2)的类型和值,并使用(*this)
(9.3.1)将引用非静态类成员的id-表达式转换为类成员访问表达式,复合语句[OF LAMBDA]被认为是在lambda表达的背景下.
所以lambda在使用成员名称时就好像它是封闭成员函数的一部分(就像在你的例子中使用名称一样x
),因此它将this
像成员函数一样生成"隐式用法" .
如果lambda-capture包含捕获默认值,则
&
lambda-capture中的标识符不得以其为前缀&
.如果lambda-capture包含一个capture-default=
,那么lambda-capture不应该包含,this
并且它包含的每个标识符都应该在前面&
.一个标识符或this
在lambda-capture中不会出现多次.
所以,你可以使用[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
Run Code Online (Sandbox Code Playgroud)
出于 lambda 捕获的目的,表达式可能会引用本地实体,如下所示:
7.3 this 表达式可能引用 *this。
因此,标准的保障this
和*this
有效,并且&this
是无效的。此外,捕获this
意味着通过引用捕获*this
(这是一个左值,对象本身),而不是通过值捕获指针!this
归档时间: |
|
查看次数: |
57206 次 |
最近记录: |