7

C++ 标准大师的几个相关问题。

传入的 C++20引入了模板 lambdas ( P0428R2 )。

所以而不是

auto x = [](auto x, auto y){ return x+y; };

我们可以指定模板参数如下

auto x = []<typename T>(T x, T y){ return x+y; };

到现在为止还挺好。

第一个问题:模板 lambdas 中的显式模板参数只能从参数推导,还是可以添加非推导的模板参数?

阅读 P0428r1 我没有看到任何明确的限制,但我也没有看到非推导模板参数的示例。

在第一个近似值中,我认为非推导模板参数是合法的,因为我看到以下愚蠢的代码

int main()
 {   
   []<int = 0>(){ }();
 }

使用 g++(10.0.0 头)和 clang++(10.0.0 头)编译和运行。

假设允许非推导的模板参数,那么第二个问题是:如何在提供模板参数的同时调用模板 lambda?

例如:给定以下模板 lambda

auto x = []<std::size_t I>(auto t){ return std::get<I>(t); };

在没有显式命名的情况下I调用此类 lambda 时是否有一些语法用于指定模板参数?operator()

我试过了

x<0u>(y);

但 the<被解释为关系运算符。

我试过简单地添加template

x template <0u>(y);

但它不起作用。

4

2 回答 2

7

lambda 函数中的模板头没有特殊限制。毕竟,Lambda 只是您已经可以在任何operator()过载情况下执行的操作的简写。

operator()在调用lambda 函数时,没有提供模板参数的特殊语法。如果您有未推导的模板参数,则必须使用传统机制来提供这些模板参数。即:lamb.operator()<Args>(...)

于 2020-01-04T16:07:24.380 回答
4

非推导的 lambda 模板参数是合法的。调用它们的语法类似于方法调用同一类的重载运算符时所需的现有函数表示法;特别是如果它是一个重载的运算符模板。

我在下面的示例中展示了最详细的组合,其中template关键字也是必需的,因为 lambda 具有依赖名称:

#include <tuple>

template <typename T>
void test()
{
  std::tuple tup{42, "eggs"};
  auto x = []<std::size_t I>(auto t){ return std::get<I>(t); };
  int i = x.template operator()<0>(tup);
}

int main(int argc, char *argv[])
{
  test<float>();
  return 0;
}
于 2021-03-06T21:41:22.437 回答