How to pass lambda as template parameter.
For example this code
template<void (*callback)()>
void function() {
callback();
}
int main() {
function<[]() -> void { std::cout << "Hello world\n"; }>();
}
fails with error "invalid template argument for 'function', expected compile-time constant expression".
What I'm doing wrong.
Edit
I want to implement something like this
template<typename T,
T (*deserializer)(buffer *data),
void (*serializer)(T item, buffer *data)>
class Type {
public:
T item;
Type(T item) : item(item) {
}
Type(buffer *data) {
deserialize(data);
}
void serialize(buffer *data) {
serializer(item, data);
}
void deserialize(buffer *data) {
deserializer(data);
}
};
typedef Type<int, [](buffer* data) -> int { return -1; }, [](int item, buffer* data) -> void {}> IntType
typedef Type<long, [](buffer* data) -> long { return -1; }, [](long item, buffer* data) -> void {}> LongType
Lambdas in C++14, including their conversion to function pointers, are not constexpr.
In C++17, this is going to change. There are no stable compilers with that feature implemented that I'm aware of (if you find one, can you mention it in the comments below?).
At that point
constexpr auto tmp = []() -> void { std::cout << "Hello world\n"; };
function<+tmp>();
will definitely work. I am uncertain if
function<+[]() -> void { std::cout << "Hello world\n"; }>()
would work; there are some rules about lambdas in unevaluated contexts and inside template argument lists that may be separate from the constexpr
lambda problem and may apply here.
We can hack it in C++14.
Create a template class that stores a static copy of a lambda and exposes a static function with the same signature (f_ptr
) that calls that static copy of a lambda.
Instantiate it once globally with your lambda.
Pass a pointer to the f_ptr
to your template.
So:
template<class L> struct stateless; // todo
template<class L> stateless<L> make_stateless(L l){return std::move(l);}
auto foo = make_stateless( []() -> void { std::cout << "Hello world\n"; } );
function< &foo::f_ptr >();
this is almost certainly not what you want.
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