Reputation: 71
I have an overload function, with the following signatures:
void Foo(const std::function<void(int )> &func);
void Foo(const std::function<void(int, int)> &func);
And when I want to use Foo() with lambdas, I'll have to do something like this:
Foo((std::function<void(int )>) [] (int i ) { /* do something */ });
Foo((std::function<void(int, int)>) [] (int i, int j) { /* do something */ });
Both of which are not so user-friendly. It'd be a lot easier to use the function without having to add the casting "(std::function<...>)" before the lambdas - like this:
Foo([] (int i ) { /* do something */ }); // executes the 1st Foo()
Foo([] (int i, int j) { /* do something */ }); // executes the 2nd Foo()
So, I need another overload, that accept lambda as its argument, and which automatically casts the lambda to one of the above signatures. How can this be done? Or, is it possible in the first place?
template <typename Function> void Foo(Function function) {
// insert code here: should be something like
// - check the signature of the 'function'; and
// - call 'Foo()' corresponding to the signature
}
Please help.
PS. I'm using VS2010.
Upvotes: 0
Views: 385
Reputation: 7302
Lambda's convert to std::function<> implicitly, there's no explicit conversion needed.
std::function<void(int, int)> func = [](int a, int b){ printf("Hello Lambda world!"); };
func(1, 2);
Ah, you're trying to get a const reference to it. Why though? You should be better off with a right-hand reference (as it's a temporary) or a copy. In both of those cases it should implicitly convert as well...
Upvotes: 1
Reputation: 55069
If your lambda does not capture any variables—that is, it begins with []
—then it is convertible to a function pointer, and you can declare Foo
like so:
void Foo(void(*func)(int));
void Foo(void(*func)(int, int));
If you want to keep the std::function
versions, you can have these versions forward to that one. If you don’t want to implement them separately, I think a variadic template would do nicely:
template<class... Args>
void Foo(void(*func)(Args...)) {
return std::function<void(Args...)>(func);
}
If your lambdas capture variables, then they’re not convertible to function pointers, and you’ll need to wrap them in std::function
yourself.
Upvotes: 3