自动参数捕获的扣除规则是什么?
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
之间建立连接。我认为参数捕获需要明确(即[a]
在第一个 lambda 中,[&a]
在嵌套中(,以便它工作。
自动参数捕获的扣除规则是什么?
这在 [expr.prim.lambda.capture]p7 中有描述:
出于 lambda 捕获的目的,表达式可能引用本地实体,如下所示:
命名本地实体的 id 表达式可能引用该实体;命名一个或多个非静态类成员且不形成指向成员的指针的id 表达式([expr.unary.op]( 可能引用
*this
。
this
表达式可能引用*this
。lambda 表达式可能引用由其简单捕获命名的本地实体。
如果表达式可能引用了该表达式在其中可用的声明性区域中的局部实体,并且如果忽略了任何封闭
typeid
表达式 ([expr.typeid]( 的效果,则表示该实体被每个干预的lambda 表达式隐式捕获,并具有未显式捕获它的关联捕获默认值。
换句话说:
如果用法需要定义,则 lambda 会在以下情况下隐式捕获,typeid
表达式将被忽略,并且不会显式捕获它们:
被命名;或者如果出现非静态类成员的名称(不计算指向成员的指针(,则隐式捕获
*this
,或者this
出现,则隐式捕获*this
隐式捕获的实体由每个具有默认捕获的干预 lambda 隐式捕获。
相关文章:
- 为什么此指针值不能转换为整数的规则是什么?
- 假设声明中某些上下文中需要的名称查找规则是什么
- 在 C++20 中对概念约束函数进行排序的规则是什么?
- 自动参数捕获的扣除规则是什么?
- c++ 17 中结构自动定义构造函数的规则是什么?
- 在 Objective-C++ 中应用于__weak指针时,通过关键字推导类型"auto"规则是什么?
- 在平等符号左侧使用RVALUE参考的规则是什么?
- 类静态变量初始化的规则是什么?
- 初始化中的模板转换运算符类型推导规则是什么?
- 将临时值存储为某种数据类型时,算术运算的标准规则是什么
- 使用“void”来专门化模板的规则是什么?
- 对于C++,在另一个函数中定义一个函数的可行性规则是什么?
- 有人能解释一下最多一次不变和存在、所有权和守恒规则是什么吗?
- 标准函数的函数指针和成员函数指针的规则是什么
- 在C++11类型推理过程中,控制优先级的规则是什么
- 从char数组中强制转换*时,严格的别名规则是什么
- 对于 C++ lambda,通过引用捕获引用的规则是什么
- decltype(右值表达式)的类型推导规则是什么
- 对于默认定义的移动构造函数,noexcept的规则是什么
- 在好友声明中使用限定名称的规则是什么?