如何调用lambda模板?

时间:2019-06-24 08:35:08

标签: c++ lambda variadic-templates

我能够使用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时出现错误。

3 个答案:

答案 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)

LIVE

答案 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...) {}

将操作符定义为模板,接受参数包,并为模板参数推导打开大门。