一些术语:
=
or内部称为capture- default &
。[&](){ /*..*/ }
- 变量的 odr-use 粗略意味着该变量不会出现在废弃值表达式(例如
(void)some_variable
or int x = some_variable, 5;
)中,也不会出现在常量表达式中。
- 复合语句是“功能块”
{
语句 }
- 变量的名称是一个id 表达式
[expr.prim.lambda]/3
lambda 表达式的类型(也是闭包对象的类型)是唯一的、未命名的非联合类类型——称为闭包类型——其属性如下所述。
/11
如果lambda 表达式具有关联的捕获默认值及其复合语句odr-uses (3.2)this
或具有自动存储持续时间的变量,并且未显式捕获使用 odr 的实体,则称使用 odr 的实体是隐式捕获;
因此,i
被隐式捕获。
/14
如果实体被隐式捕获并且默认捕获是,=
或者如果使用不包含&
. 对于通过副本捕获的每个实体,在闭包类型中声明了一个未命名的非静态数据成员。
闭包类型中有一个非静态数据成员(类型为int
)。
/17
复制捕获的实体的 odr-use (3.2) 的每个id 表达式都转换为对闭包类型的相应未命名数据成员的访问。
我们甚至不需要解释这一点,因为本段为我们提供了一个与 OP 非常相似的示例:
void f(const int*);
void g() {
const int N = 10;
[=] {
int arr[N]; // OK: not an odr-use, refers to automatic variable
f(&N); // OK: causes N to be captured; &N points to the
// corresponding member of the closure type
};
}
如果我们将此应用于 OP 的示例,我们会看到它&i
指的是闭包类型的内部非静态数据成员。标准中未指定诊断消息是否合适;)