MichaelMitchell MichaelMitchell - 2 months ago 5
C++ Question

pass lambda to function that accepts function with templated types

I'm attempting to make a template function that takes a function as a parameter and the parameter function has arguments for the template to deduce.

Example time:

Here is a function that accepts a fixed function type and works

void func_a(void(*func)(int)) {
func(1);
}
int main() {
auto f = [](int x) -> void { printf("%i\n", x); };
func_a(f);
return 0;
}


Here is what I want to do, expanding on the first example (this won't compile)

template <typename... T>
void func_b(void(*func)(T...)) {
func(1);
}
int main() {
auto f = [](int x) -> void { printf("%i\n", x); };
func_b(f); // neither of
func_b<int>(f); // these work
return 0;
}


Ideally I'd like
func_b
to accept both a regular function and a lambda function like
func_a
does, but with template magics.

Answer

Unfortunately, template deduction doesn't work well with implicit conversions. However, you can convert the lambda explicitly into a function pointer type. The shortest, but somewhat confusing way to do that is to apply unary + operator:

func_b(+f);

Or you could use the more intuitive, but also verbose and DRY-violating cast operation:

func_b(static_cast<void(*)(int)>(f));

But perhaps, you'll want to simply accept any callable type, instead of only function pointers:

template <class Fun>
void func_c(Fun&& func) {
    func(1);
}

This works fine with lambdas. No conversions involved.

func_c(f);

And it also works for capturing lambdas (that cannot be converted to function pointers), std::function and function objects such as those defined in <functional>.