非局部 lambda 和捕获变量 - "block scope"是什么意思

Non local lambda and capturing variables - what does "block scope" means

本文关键字:block scope 是什么 意思 变量 lambda 非局      更新时间:2023-10-16

我目前正在玩 c++11 lambdas,发现了一个我无法理解的例子。根据标准:

最小封闭作用域为块作用域 (3.3.3) 的 lambda 表达式是局部 lambda 表达式;any 其他 lambda 表达式在其 lambda 介绍器中不应有捕获列表

所以,我创建了一个琐碎的例子:

int a = 10;
auto x  = [a] { return 1;};
int main() {
    int k = 5;
    auto p = [k]{ return k; };
    return 0;
}

ideone中的代码:http://ideone.com/t9emu5

我预计这段代码不会编译,因为在非块范围内捕获变量(或者至少认为自动 x = ...部分不在块范围内)。但是代码正在编译 - 可以吗?

如果可以 - 块范围是什么?

(我不确定我使用的编译器版本,因为目前我只能访问 ideone 站点。

感谢您的解释!

看起来这是一个编译器扩展。 G++4.8.1 在给出警告的同时编译它:

警告:捕获具有非自动存储持续时间的变量"A" [默认启用]

clang++3.4 不会编译这个:

错误:无法捕获"A",因为它没有自动存储持续时间

两者都指 [expr.prim.lambda]/10

捕获列表中的标识符使用非限定名称查找的常规规则(3.4.1)进行查找;每个此类查找都应找到一个变量,该变量具有在本地 lambda 表达式的到达范围内声明的自动存储持续时间。

似乎他们没有另外检查 lambda 的封闭范围,我可以想象这将是多余的(在非块/命名空间范围内没有具有自动存储持续时间的变量名称)。


块作用域在 [basic.scope.block]/1 中定义

在块 (6.3) 中声明的名称是该块的本地名称;它具有块范围。

块定义为:

为了在预期的地方可以使用多个语句,提供了复合语句(也等效地称为"块")。

     复合语句:
         {语句-序列选择}

所以你是对的,你的全局声明的 lambda 不在块范围内。