简体   繁体   中英

limits and uses of C++20 template lambas

A couple of related questions for C++ standard gurus.

The incoming C++20 introduces template lambdas ( P0428R2 ).

So instead of

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

we can specify the template parameter as follows

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

So far, so good.

First question: can explicit template parameters, in template lambdas, only be deduced from arguments, or is it possible to add non-deduced template arguments?

Reading P0428r1 I don't see any explicit limitations but, also, I don't see examples of non-deduced template arguments.

In first approximation I suppose that non-deduced template arguments are legal because I see that the following silly code

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

compiles and runs with both g++ (10.0.0 head) and clang++ (10.0.0 head).

Supposing that non-deduced template parameters are allowed, the second question is: how can I call a template lambda while providing a template parameter?

By example: given the following template lambda

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

Is there some syntax for specifying the template parameter I when invoking such lambdas without explicitly naming operator() ?

I've tried with

x<0u>(y);

but the < is interpreted as a relational operator.

I've tried simply adding template

x template <0u>(y);

but it doesn't work.

There are no special restrictions on template headers in lambda functions. Lambdas are after all just shorthand for what you could do already with any operator() overload.

There is no special syntax for providing template arguments when invoking the operator() of a lambda function. If you have template parameters which are not deduced, you will have to use the traditional mechanisms for providing those template arguments. IE: lamb.operator()<Args>(...) .

Non-deduced lambda template arguments are legal. The syntax for calling them is similar to the existing function notation required when a method calls an overloaded operator of the same class; and especially if it is an overloaded operator template.

I show the most verbose combination in the example below, where the template keyword is also required as the lambda has a dependent name:

#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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM