2013-10-13 23 views
8

我目前与C++ 11个lambda表达式玩,我发现我无法理解一个例子。根据标准:非本地Lambda和捕捉变量 - 什么是“块范围”是指

A lambda-expression whose smallest enclosing scope is a block scope (3.3.3) is a local lambda expression; any other lambda-expression shall not have a capture-list in its lambda-introducer

所以,我创建了简单的例子:http://ideone.com/t9emu5

我期待这个代码将不会因为在拍摄变量的编译:

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

在ideone代码非块范围(或者至少认为auto x = ...部分不在块范围内)。但代码正在编译 - 可以吗?

如果是正常 - 块范围是什么?

(我不知道我所用的编译器版本,因为目前我只有ideone站点的访问。

感谢解释!

+0

那么,什么范围是非块范围? – matekm

+1

@DanielFrey Huh?一个块是一个复合语句,而一个名称空间当然不是一个块。请参阅[basic.scope.block]/1和[stmt.block] – dyp

+0

@DyP对不起,我感到困惑。你完全正确! –

回答

12

看起来这是一个编译器扩展。G ++ 4.8 0.1编译此同时发出警告:

warning: capture of variable ‘a’ with non-automatic storage duration [enabled by default]

铛++ 3.4不能编译如下:

error: 'a' cannot be captured because it does not have automatic storage duration

均指[expr.prim.lambda]/10

The identifiers in a capture-list are looked up using the usual rules for unqualified name lookup (3.4.1); each such lookup shall find a variable with automatic storage duration declared in the reaching scope of the local lambda expression.

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


块范围在[basic.scope.block]/1

A name declared in a block (6.3) is local to that block; it has block scope.

定义和块定义为:

So that several statements can be used where one is expected, the compound statement (also, and equivalently, called “block”) is provided.

     compound-statement:
         {statement-seqopt}

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

+0

非常感谢! – matekm

+0

补充:您可以GCC拒绝通过使用编译标志'-pedantic-errors'(除了'-std = C++ 11'),我建议(和'-Wall -Wextra'太)。 Ideone不允许您指定编译器选项,但例如[Coliru](http://coliru.stacked-crooked.com/)也是([GCC Explorer](http://gcc.godbolt.org/)),但它只编译(并显示程序集输出),它不会连接并运行)。 (请参阅http://isocpp.org/get-started以获取更多在线C++编译器。) –

+0

@gx_这似乎是错误的。我用'-Wall -Wextra -Wpedantic'进行编译,并且从未在我的代码中告诉过这个错误(这可能是将lambda从本地作用域移出的结果),跨g ++'版本5和现在6.1。毫无疑问,加入'-pedantic-errors'不会改变这一点。 'g ++'只是不警告我。我想我需要更经常地问'clang ++'第二个意见......叹气 –