自动参数捕获的推导规则是什么?
What are the deduction rules for automatic argument capture?
我之前看到了这段代码的等价物,得知它按预期工作时我有点惊讶:
#include <iostream>
int main()
{
int a = 10;
[=]() mutable {
[&]() {
a += 10;
std::cout << "nested lambda: a=" << a << std::endl;
}(); // call nested lambda
}(); // call first lambda
std::cout << "a=" << a << std::endl;
}
正如所希望的那样,输出是
nested lambda: a=20
a=10
令我惊讶的是,编译器发现 a
在嵌套的 lambda 中使用,并在第一个 lambda 中按值正确捕获它,即使它没有在那里明确使用。即,编译器必须在嵌套 lambda 中的 a
和外部作用域中的 a
之间建立连接。我认为参数捕获需要是显式的(即第一个 lambda 中的 [a]
,嵌套中的 [&a]
),它才能工作。
自动参数捕获的推导规则是什么?
这在[expr.prim.lambda.capture]p7中有描述:
For the purposes of lambda capture, an expression potentially references local entities as follows:
An id-expression that names a local entity potentially references that entity; an id-expression that names one or more non-static class members and does not form a pointer to member ([expr.unary.op]) potentially references *this
.
A this
expression potentially references *this
.
A lambda-expression potentially references the local entities named by its simple-captures.
If an expression potentially references a local entity within a declarative region in which it is odr-usable, and the expression would be potentially evaluated if the effect of any enclosing typeid
expressions ([expr.typeid]) were ignored, the entity is said to be implicitly captured by each intervening lambda-expression with an associated capture-default that does not explicitly capture it.
换句话说:
如果使用需要定义,lambda 在以下情况下会隐式捕获,typeid
表达式将被忽略,并且不会显式捕获它们:
一个变量被命名;或者如果出现非静态 class 成员的名称(不计算指向成员的指针),则 *this
被隐式捕获,或者
this
出现,然后*this
被隐式捕获
隐式捕获的实体由每个具有默认捕获的中间 lambda 隐式捕获。
我之前看到了这段代码的等价物,得知它按预期工作时我有点惊讶:
#include <iostream>
int main()
{
int a = 10;
[=]() mutable {
[&]() {
a += 10;
std::cout << "nested lambda: a=" << a << std::endl;
}(); // call nested lambda
}(); // call first lambda
std::cout << "a=" << a << std::endl;
}
正如所希望的那样,输出是
nested lambda: a=20
a=10
令我惊讶的是,编译器发现 a
在嵌套的 lambda 中使用,并在第一个 lambda 中按值正确捕获它,即使它没有在那里明确使用。即,编译器必须在嵌套 lambda 中的 a
和外部作用域中的 a
之间建立连接。我认为参数捕获需要是显式的(即第一个 lambda 中的 [a]
,嵌套中的 [&a]
),它才能工作。
自动参数捕获的推导规则是什么?
这在[expr.prim.lambda.capture]p7中有描述:
For the purposes of lambda capture, an expression potentially references local entities as follows:
An id-expression that names a local entity potentially references that entity; an id-expression that names one or more non-static class members and does not form a pointer to member ([expr.unary.op]) potentially references
*this
.A
this
expression potentially references*this
.A lambda-expression potentially references the local entities named by its simple-captures.
If an expression potentially references a local entity within a declarative region in which it is odr-usable, and the expression would be potentially evaluated if the effect of any enclosing
typeid
expressions ([expr.typeid]) were ignored, the entity is said to be implicitly captured by each intervening lambda-expression with an associated capture-default that does not explicitly capture it.
换句话说:
如果使用需要定义,lambda 在以下情况下会隐式捕获,typeid
表达式将被忽略,并且不会显式捕获它们:
一个变量被命名;或者如果出现非静态 class 成员的名称(不计算指向成员的指针),则
*this
被隐式捕获,或者this
出现,然后*this
被隐式捕获
隐式捕获的实体由每个具有默认捕获的中间 lambda 隐式捕获。