我能够使用gcc编译以下代码:
template<typename... Pack>
auto func(Pack... x) {
return (x + ...) ;
}
template<typename... Pack>
auto lamd = [](Pack... x) {
return (x + ...) ;
};
我可以使用func(1,2,3)
调用函数模板,但是在调用lamd(1,2,3)
或lamd<int>(1,2,3)
的lambda时出现错误。
答案 0 :(得分:4)
对于lambda,您可以使用auto
将其设置为generic lambda。
auto lamd = [](auto... x) {
return (x + ...) ;
};
自C ++ 20起,您可以使用显式模板参数列表,但是请注意,模板参数列表仍与lambda的operator()
一起使用,就像使用auto
参数一样。例如
auto lamd = []<typename... Pack>(Pack... x) {
return (x + ...) ;
};
,然后您可以将其称为lamd(1,2,3)
。
答案 1 :(得分:3)
没有lambda模板之类的东西。 Lambda表达式始终是唯一的新类型。特别是,它不是可用于实例化实际功能的模板。
但是,lamdba提供的函数调用运算符可以是模板。您也可以免费获得语法:
auto lamd = [](auto... x) {
return (x + ...) ;
};
请注意,C ++ 2a将附带通用lambda的附加支持和明确性,并允许您
auto lambda = []<typename...T>(T&& ...args) { /* ... */ };
但这不会影响您在此处面临的问题。
答案 2 :(得分:3)
第二个定义是变量模板。它没有将lambda的operator()
定义为模板,而是将参数包用于operator()
的参数类型。结果operator()
是实例化变量的闭包类型的常规成员函数。此处无法进行模板参数推导。
因此,当您编写lamd<int>
时,该变量的闭包类型为operator()(int)
,而不能用3个整数调用。
如前所述,您可以改用通用lambda。
在C ++ 20中,如果需要命名和推导lambda的参数类型,则可以使用以下语法:
auto lamd = []<typename... Pack>(Pack...) {}
此将将操作符定义为模板,接受参数包,并为模板参数推导打开大门。