I have a template that accepts a function as an argument.
When I try to pass a lambda expression it does not compile.
typedef int (*func)(int a);
template <func foo>
int function(int a)
{
foo(a);
}
int test(int a)
{
return a;
}
int main()
{
function<test>(1); // ---> this is ok
auto lambda = [](int a) -> int { return a; };
function<lambda>(1); // ---> this is wrong, why?
return 0;
}
What I am missing?
A lambda is not a function pointer! A lambda is an instance of compiler generated class!
However, a non capturing lambda may be converted to a function pointer using it's
operator+
Here's an example:
Sadly, the
operator+
won't even work in your case because it has not been declared as constexpr, so you can't use it in a template parameter.A fix to your case would be to use a free function... until N4487 is not accepted, you can't expect to pass lambda as template parameter.
Another fix would be to create your own functor instead of a lambda:
This solution is not quite appealing, but it might be useful if
LambdaType
is hidden in a cpp file.If your goal is only the compiler to be able to inline your code, you can use templates to pass the lambda around:
Since the compiler knows the type of
T
for each instanciation, a good compiler should be able to optimize out the lambda.With clang, the third option gives the following assembly:
I used
-std=c++14 -Ofast -march=native
as flags.This is because the lambda as its own type.
You have templatize
function()
on the type of the function passed.I do not know enough of the standard to say whether this is my compilers fault not implementing it properly or if it's actually the standard, but with VS2015 you cannot generate a compile-time constant lambda expression. And templates only take compile time constants, so no lambdas.
However, you don't need it to be a template if you want to pass a lambda. It's perfectly possible without:
This is only because "You cannot use the name or address of a local variable as a template argument.". If you want to make a global static lambda, go refer to http://pfultz2.com/blog/2014/09/02/static-lambda/ you may find what you want.