C++20 introduces full template support for lambda functions on par with the regular template functions. The full template syntax for a lambda adds
a template-arguments clause after the capture clause completing the panoply of brackets: []<>(){}. For example:
[]<typename T>(T arg) { return arg; }
Although more verbose than using auto
for the types of the arguments, this syntax enables you to name the types for the parameters,
constrain these types (see Concepts), and reuse these types for multiple arguments.
One common use case for the named template argument is a lambda with multiple arguments of the same type. Pre-C++20 code had to resort to the use
of decltype
: [](auto arg1, decltype(arg1) arg2) ...
. Not only is it obscure it also only approximates our goal: it requires
the second-argument type to be convertible to the first-argument type.
Moreover, similar issues may appear for normal functions, that declare parameters with auto
in place of type using C++20 abbreviated
template syntax.
This rule reports the use of decltype(arg)
for parameters introduced with auto
.
Noncompliant code example
void f1() {
auto sum = [](auto fir, decltype(fir) sec) { return fir + sec; }; // Noncompliant
std::cout << sum(true, 1); // Prints 2
}
void f2(auto param) { // Noncompliant
decltype(param) copy = param;
}
Compliant solution
void f1() {
auto sum = []<class T>(T fir, T sec) { return fir + sec; }; // Compliant
// std::cout << sum(true, 1); - compilation error
}
template<class T>
void f2(T param) { // Compliant
T copy = param;
}