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

C++ 是[]<;typename>;(){}一个有效的lambda定义?,c++,gcc,lambda,clang,language-lawyer,C++,Gcc,Lambda,Clang,Language Lawyer,我一直在试验lambdas和编译器,因为这里是如此。 我刚刚意识到(这是非常正常的)以下代码是有效的: int main() { auto l = [](){}; l.operator()(); } 实际上,标准中说闭包类型有一个公共内联函数调用操作符等等,因此能够调用它是有意义的 通过查看标准(工作草案)我无法解释的是,GCC(6.1)编译了以下代码片段(clang 3.9没有): intmain(){ 自动l=[](){}; l、 运算符(); } 没有警告,没有错误。它

我一直在试验lambdas和编译器,因为这里是如此。
我刚刚意识到(这是非常正常的)以下代码是有效的:

int main() {
    auto l = [](){};
    l.operator()();
}
实际上,标准中说闭包类型有一个公共内联函数调用操作符等等,因此能够调用它是有意义的

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

intmain(){
自动l=[](){};
l、 运算符();
}

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

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

lambda介绍人lambda声明人opt复合语句

其中,“lambda介绍人”是
[]
,包含可选的“lambda捕获”和以“(参数声明子句)”开头的“lambda声明器opt”

[](){}
不满足该要求,因为lambda介绍器和lambda声明器之间存在某种差异,因此它不是有效的lambda表达式

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


由于这也被标记,我点击了列表中的。我没有发现任何扩展,这将使语法在GNU C++中成为合法的。
然而,根据(P0428 R0)第4节,提出了将模板化的LAMBDAS添加到C++中,GCC在2009中得到了上述论文的实验实现。这可能解释了为什么gcc在这里没有抱怨。

它似乎是一个gcc扩展(模板化的lambdas)

#包括
int main(){

auto l=[](T const&x){std::cout给定的代码格式良好,自C++20以来一直按预期工作

Per:

lambda表达式:
lambda介绍人lambda声明人opt复合语句
lambda介绍人
需要clauseopt lambda declaratoropt复合语句

最后一行反映了此语法。根据:

如果decl说明符为,则lambda是泛型lambda 的decl说明符序列中的占位符类型说明符 lambda表达式的参数声明,或lambda是否有模板参数列表。


@amanuel2我知道它可以编译(至少使用GCC),但问题是它是否有效。C++14将允许“模板化”lambda,但这是使用
auto
关键字,而不是
模板语法(请参阅)。也许GCC开发人员想尝试不同的方法来添加此类功能?FWIW,我建议在中更改此行为。这将是Issaquah之前邮件的一部分。@LouisDionne:您在论文中提到此扩展是在2009年在GCC中实现的,这能解释为什么GCC接受此代码,尽管它是这是不标准的,因此值得一个答案。如果问题被标记为GCC,在这方面值得检查GNU扩展是否符合标准。@ VALITY同意,补充。谢谢。我已经向GCC打开了一个问题,是否值得一提?@ SkyPokes如果它添加了信息,比如DEV,确认它们是否认为它是一个bug,我认为这会很有帮助。请随意在中编辑。@BaummitAugen好的,我会看看它是如何发展的,如果需要的话,我会在中编辑。谢谢。你能提供一个指向此文档的链接吗?我找不到它,这就是为什么我排除了作为扩展的可能性。谢谢。是我能找到的最接近@skypjack的吗
int main() {
    auto l = []<typename>(){};
    l.operator()<void>();
}
[]<typename>(){}
#include <iostream>

int main() {
    auto l = []<typename T>(T const& x){ std::cout << __PRETTY_FUNCTION__ << " " << x << std::endl;};
    l(42);
    l("Hello world");
}
main()::<lambda(const T&)> [with T = int] 42
main()::<lambda(const T&)> [with T = char [12]] Hello world