如何调用 lambda 模板?

How to invoke a lambda template?

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

对于 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

不存在 lambda 模板这样的东西。 lambda 表达式始终是唯一的新类型。特别是,它不是可用于实例化实际功能的模板。

但是,lamdba 提供的函数调用运算符可以是模板。您也可以免费获得语法:

auto lamd = [](auto... x) {
    return (x + ...) ;
};

请注意,C++2a 将附带对通用 lambda 的额外支持和明确性,并允许您

auto lambda = []<typename...T>(T&& ...args) { /* ... */ };

但这不会影响您在这里遇到的问题。

第二个定义是变量模板。它没有将 lambda 的 operator() 定义为模板,而是采用 operator() 的参数类型的参数包。结果 operator() 是实例化变量闭包类型的常规成员函数。这里不可能推导模板参数。

所以当你写 lamd<int> 时,变量得到一个带有 operator()(int) 的闭包类型,而不是可以用 3 个整数调用的东西。

如前所述,您可以改用通用 lambda。

在 C++20 中,如果您需要命名和推导 lambda 的参数类型,您可以使用语法:

auto lamd = []<typename... Pack>(Pack...) {}

将运算符定义为模板,接受参数包,并为模板参数推导敞开大门。