pin*_*gul 10 c++ lambda c++11 argument-deduction
我之前看到了相当于这段代码的东西,我有点惊讶地发现它按预期工作:
#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;
}
Run Code Online (Sandbox Code Playgroud)
如期望的那样,输出是
nested lambda: a=20
a=10
Run Code Online (Sandbox Code Playgroud)
令我感到惊讶的是编译器发现a在嵌套的lambda中使用了它,并且正确地在第一个lambda中按值捕获它,即使它没有在那里明确使用.即,编译器必须a在嵌套的lambda和a外部作用域之间建立连接.我认为参数捕获需要是显式的(即[a]在第一个lambda中,[&a]在嵌套中),才能使它工作.
自动参数捕获的演绎规则是什么?
这在[expr.prim.lambda.capture] p7中有描述:
出于lambda捕获的目的,表达式可能引用本地实体,如下所示:
命名本地实体的id表达式可能引用该实体; 一个id-expression,它命名一个或多个非静态类成员,并且不构成指向成员([expr.unary.op])潜在引用的指针
*this.甲
this表达潜在的引用*this.一个拉姆达表达式可能引用由它的简单,捕获命名的本地实体.
如果表达式可能引用声明区域内的本地实体,并且该表达式可以使用,并且如果
typeid忽略任何封闭表达式([expr.typeid])的效果,则可能会评估该表达式,该实体被称为每个插入的lambda表达式都隐式捕获了一个没有明确捕获它的相关捕获默认值.
换一种说法:
如果用法需要定义,typeid表达式被忽略,并且未明确捕获它们,则lambda会在以下情况下隐式捕获:
变量被命名; 或者如果出现非静态类成员的名称(不计入指向成员的指针),则*this隐式捕获,或者
this出现,然后*this被隐含地捕获
每个插入的lambda使用默认捕获隐式捕获隐式捕获的实体.