我之前看到过这段代码的等价物,得知它按预期工作时我有点惊讶:
#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
表达式将被忽略,并且它们不会被显式捕获:
一个变量被命名;或者如果出现非静态类成员的名称(不包括指向成员的指针),则
*this
被隐式捕获,或者this
出现,然后*this
被隐式捕获
隐式捕获的实体由每个具有默认捕获的中间 lambda 隐式捕获。
关于c++ - 自动参数捕获的推导规则是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51759044/