0

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.

1
  • What compiler are you using, and what version? By the way, works fine in clang 3.3 (trunk 177501). Commented Apr 9, 2013 at 5:41

2 Answers 2

3

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Sorry, I didn't mention that I'm using VS2010, which does not allow lambda-to-function-pointer conversion. I guess I'll have to change my compiler or live with it then... Many thanks!
1

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...

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.