【问题标题】:How to invoke a lambda template?如何调用 lambda 模板?
【发布时间】:2019-11-06 00:48:10
【问题描述】:

我能够使用 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&lt;int&gt;(1,2,3) 调用 lambda 时出现错误。

【问题讨论】:

标签: c++ lambda variadic-templates


【解决方案1】:

对于 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 吗?
  • @Nujufas 答案已修改。
【解决方案2】:

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

因此,当您编写 lamd&lt;int&gt; 时,该变量将获得带有 operator()(int) 的闭包类型,而不是可使用 3 个整数调用的类型。

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

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

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

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

【讨论】:

    【解决方案3】:

    没有像 lambda 模板这样的东西。 lambda 表达式始终是唯一的新类型。特别是,它不是一个可用于实例化实际函数的模板。

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-22
      • 2020-02-08
      相关资源
      最近更新 更多