[] <typename>(){}是一个有效的lambda定义吗?

sky*_*ack 23 c++ lambda gcc clang language-lawyer

我正在尝试使用lambdas和编译器,因为这里有另一个问题.
我刚刚意识到(并且确实非常正常)以下代码是有效的:

int main() {
    auto l = [](){};
    l.operator()();
}
Run Code Online (Sandbox Code Playgroud)

实际上标准说闭包类型有一个公共内联函数调用操作符等等,因此能够调用它是有意义的.

通过查看标准(以及工作草案)我无法解释的是,GCC(6.1)编译了以下代码段(clang 3.9没有):

int main() {
    auto l = []<typename>(){};
    l.operator()<void>();
}
Run Code Online (Sandbox Code Playgroud)

没有警告,没有错误.它是有效的代码还是被编译器拒绝?

Bau*_*gen 21

在N4140 5.1.2 [expr.prim.lambda]中,Lambda表达式定义为

lambda-introducer lambda-declarator opt复合语句

其中一个"lambda-introducer"[],包含一个可选的"lambda-capture""lambda-declarator opt "是以"(parameter-declaration-clause)"开头的东西.

[]<typename>(){}
Run Code Online (Sandbox Code Playgroud)

不符合该要求,因为lambda介绍者和lambda声明符之间存在某种东西,因此它不是有效的lambda表达式.

因此,您的示例代码不是有效的C++,应该被编译器拒绝.


由于这也标记为,我点击了GNU C++扩展列表.我没有找到任何可以使GNU C++中的语法合法的扩展.

然而,根据该提案的第4节(P0428R0),该提议将模板化的lambda添加到C++中,gcc在2009年得到了上述论文的实验性实现.这可能解释了为什么gcc不会在这里抱怨.

  • 鉴于该问题是标记为GCC,值得检查在这方面是否存在标准的gnu扩展. (4认同)