The code below doesn't compile on gcc 4.5 because the call to foo is ambiguous. What is the correct way to disambiguate it?
#include <iostream>
#include <functional>
using namespace std;
void foo(std::function<void(int, int)> t)
{
t(1, 2);
}
void foo(std::function<void(int)> t)
{
t(2);
}
int main()
{
foo([](int a, int b){ cout << "a: " << a << " b: " << b << endl;});
}
I've recently been thinking about a similar problem and when looking around for any known solutions I came across this post and lack of solutions for resolving
An alternative solution is to abstract over the functor as a template argument and use decltype to resolve its type. So, the above example would become:
This works as expected with gcc 4.5.
The best way is to explicitly create a
std::function
object of the correct type then pass that object to the function:or inline:
std::function
has a constructor template that accepts anything:Because of this, there's no way for the compiler to know during overload resolution which
foo
to select: bothstd::function<void(int)>
andstd::function<void(int, int)>
have a constructor that can take your lambda expression as an argument.When you pass a
std::function
object directly, thestd::function
copy constructor is preferred during overload resolution, so it is selected instead of the constructor template.Answer for the future: If the capture list is guaranteed to be empty, you can also use ordinary function pointers. In C++0x, a captureless lambda is implicitly convertible to a function pointer. So, you can use something like
and call
foo
directly with the captureless lambda (or a function pointer with matching type).Note that this conversion is a very recent addition to the draft language standard (it was added in February of this year), so it is not likely to be widely supported yet. Visual C++ 2010 doesn't support it yet; I don't know about the latest g++.