Is the following code legal?
template <auto Lambda>
struct A {};
int main () {
auto lmb = [](int i){return i*i;};
A<lmb> a;
return 0;
}
I noticed that g++ compiles it fine, while clang++ returns
error: a non-type template parameter cannot have type '(lambda at main.cpp:...)'
.
Can lambdas be used as non-type template parameter?
Yes, with implementations that has implemented P0732R2 - Class types in non-type template parameters but clang++
has not implemented it yet.
Source: https://en.cppreference.com/w/cpp/compiler_support
Note that the lambda needs to be at least constexpr
(which it is by default):
When this specifier is not present, the function call operator will be
constexpr
anyway, if it happens to satisfy allconstexpr
function requirements.
You can however add constexpr
to get an error on the lambda itself instead of when using it as a template parameter. As a side note: You can also specify it to be consteval
to make it work as a non-type template parameter.
A stateful lambda can be constexpr
:
constexpr auto lmb1 = [](int i) {
static int x = 0;
return i*i + ++x;
};
while a lambda capturing by reference, or capturing by copy and mutating (mutable
), can not. Capturing by copying a constexpr
is ok though.
Generic lambdas may be constexpr
too:
constexpr auto gen_lmb = []<typename T>(T& val) {
val += val;
return val;
};
template <auto Lambda>
struct A {
template<typename T>
void doit(T&& arg) {
std::cout << Lambda(arg) << '\n';
}
};
//...
A<gen_lmb> ginst;
int v = 1000;
ginst.doit(v);
ginst.doit(std::string("foo "));
std::cout << v << '\n';
2000
foo foo
2000
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