Is it possible to pass a lambda function as a function pointer? If so, I must be doing something incorrectly because I am getting a compile error.
Consider the follo
Capturing lambdas cannot be converted to function pointers, as this answer pointed out.
However, it is often quite a pain to supply a function pointer to an API that only accepts one. The most often cited method to do so is to provide a function and call a static object with it.
static Callable callable;
static bool wrapper()
{
return callable();
}
This is tedious. We take this idea further and automate the process of creating wrapper
and make life much easier.
#include
#include
template
union storage
{
storage() {}
std::decay_t callable;
};
template
auto fnptr_(Callable&& c, Ret (*)(Args...))
{
static bool used = false;
static storage s;
using type = decltype(s.callable);
if(used)
s.callable.~type();
new (&s.callable) type(std::forward(c));
used = true;
return [](Args... args) -> Ret {
return Ret(s.callable(std::forward(args)...));
};
}
template
Fn* fnptr(Callable&& c)
{
return fnptr_(std::forward(c), (Fn*)nullptr);
}
And use it as
void foo(void (*fn)())
{
fn();
}
int main()
{
int i = 42;
auto fn = fnptr([i]{std::cout << i;});
foo(fn); // compiles!
}
Live
This is essentially declaring an anonymous function at each occurrence of fnptr
.
Note that invocations of fnptr
overwrite the previously written callable
given callables of the same type. We remedy this, to a certain degree, with the int
parameter N
.
std::function func1, func2;
auto fn1 = fnptr(func1);
auto fn2 = fnptr(func2); // different function