Search code examples
c++lambdalanguage-lawyerc++20generic-lambda

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.


Solution

  • 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>(...).