[]<typename>(){} 是有效的 lambda 定义吗?
Is []<typename>(){} a valid lambda definition?
我正在尝试使用lambdas和编译器,因为这里有另一个关于SO的问题。
我刚刚意识到(这确实很正常)下面的代码是有效的:
int main() {
auto l = [](){};
l.operator()();
}
实际上,标准规定闭包类型有一个公共内联函数调用操作符等等,因此能够调用它是有意义的。
我不能通过查看标准(好吧,工作草案)来解释的是,GCC(6.1)编译了以下代码片段(clang 3.9没有):
int main() {
auto l = []<typename>(){};
l.operator()<void>();
}
没有警告,没有错误。它是有效的代码还是应该被编译器拒绝?
在N4140 5.1.2 [expr.prim.]lambda], lambda表达式定义为
opt compound-statement
其中"lambda-introducer"是[]
,包含一个可选的"lambda-capture"和"lambda-declaratoropt"是以开头的东西"(parameter-declaration-clause)"。
[]<typename>(){}
不满足这个要求,因为在lambda引入器和lambda声明器之间有一些东西,所以它不是一个有效的lambda表达式。
因此,你的示例代码不是有效的c++,应该被编译器拒绝。
因为它也被标记为gcc,所以我点击了GNU c++扩展列表。我没有找到任何可以使有问题的语法在GNU c++中合法的扩展。
然而,根据该提案(P0428R0)的第4节,该提案建议在c++中添加模板化的lambdas, gcc在2009年获得了上述论文的实验性实现。这可能解释了为什么gcc在这里没有抱怨。
这似乎是一个GCC扩展(模板化的lambdas)。
#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
给出的代码格式良好,从c++ 20开始按预期工作。
每[expr.prim.lambda]:lambda-expression:
lambda-declaratoropt compound-statement
,,, lambda-introducer<
template-parameter-list>
requiresclause opt lambda-declaratoropt compound-statement
最后一行反映了这种语法。每(expr.prim.lambda)/5:
如果存在decl-specifier,则lambda是泛型lambdaA的decl- specific -seq中的占位符类型说明符lambda表达式的参数声明, 或者如果lambda有模板参数列表。
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 欧拉项目#8答案是大以获得有效答案
- 可组合的lambda/std::函数与std::可选
- 调整大小后指向元素值的指针unordered_map有效?
- 为什么是0;C++中的有效语句
- 最高有效数字侧的第N位
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- GCC对可能有效的代码抛出init list生存期警告
- 如何建立使用模板函数的lambda函数的尾部返回类型
- 有效地使用std::unordered_map来插入或增加键的值
- c++中O(n^(1/3))中一个数的除数的有效计数
- 使用无符号字符数组有效存储内存
- 自定义先决条件对移动分配运算符有效吗
- 如何将lambda作为模板类的成员函数参数
- 为什么 lambda nullptr 取消引用在这种情况下有效?
- 为什么在三元运算符的分支之间返回 lambda 对某些 lambda 有效?
- 通用lambda,继承和尾随返回类型:此有效代码
- []<typename>(){} 是有效的 lambda 定义吗?
- C++: boost::asio: async_resolve() 不起作用(使用 lambda 函数),但 resolve() 有效
- 在编译时,我能告诉Boost.Fenix lambda的一组特定输入类型是否有效吗