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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With