Reputation: 960
I have a template class with a static member variable that I want to be a lambda function. Why doesn't it work?
#include <iostream>
using namespace std;
template <typename T>
class Test {
public:
static constexpr auto lambda = [](T val) -> T {
return val;
};
};
int main() {
cout << Test<int>::lambda(123) << endl;
}
I tried both version with constexpr and const.
In the first case I get:
../src/test.cpp:8:24: error: ‘constexpr const Test<int>::<lambda(int)> Test<int>::lambda’, declared using local type ‘const Test<int>::<lambda(int)>’, is used but never defined [-fpermissive]
static constexpr auto lambda = [](T val) -> T {
^~~~~~
In the second case:
../src/test.cpp:7:20: error: ‘constexpr’ needed for in-class initialization of static data member ‘const Test<int>::<lambda(int)> Test<int>::lambda’ of non-integral type [-fpermissive]
static const auto lambda = [](T val) -> T {
^~~~~~
../src/test.cpp:7:20: error: ‘const Test<int>::<lambda(int)> Test<int>::lambda’, declared using local type ‘const Test<int>::<lambda(int)>’, is used but never defined [-fpermissive]
Upvotes: 1
Views: 826
Reputation: 7447
A core constant expression may contain a lambda only starting from C++17 (see cppreference point 8). This was proposal N24487 and got into C++17 as P0170R0.
If you have to use a static lambda, you can make use of the construct at first use idiom:
#include <iostream>
template <typename T>
class Test {
public:
std::function<T(T)> createLambda() {
static const std::function<T(T)> returnLambda = [](T val) -> T {
return val;
};
return returnLambda;
}
};
int main() {
Test<int> lambdaFactory;
std::function<int(int)> n = lambdaFactory.createLambda();
std::cout << n(123) << std::endl;
}
Upvotes: 2