I have two overloads of a function foo
which take different std::function
s which results in an ambiguity issue for the latter when used with the result of a std::bind
. I don't understand why only this is ambiguous.
void foo(std::function<void(int)>) {}
void foo(std::function<int()>) {}
void take_int(int) { }
int ret_int() { return 0; }
When using int()
with a bind
function I get an ambiguity error
foo(std::bind(ret_int)); // ERROR
With the gcc-5.1 error (and similar with clang)
error: call to 'foo' is ambiguous
foo(std::bind(ret_int));
^~~
note: candidate function
void foo(std::function<void(int)>) {}
^
note: candidate function
void foo(std::function<int()>) {}
However all of the following work
foo(std::bind(take_int, _1));
foo(take_int);
foo(ret_int);
foo([](){ return ret_int(); });
struct TakeInt {
void operator()(int) const { }
};
struct RetInt {
int operator()() const { return 0; }
};
foo(TakeInt{});
foo(RetInt{});
Looking at the std::function
constructor
template< class F >
function( F f );
it would make sense to me that any function with multiple overloads on different std::function
types should have ambiguities, but it's only an issue with the call to bind. I then thought "maybe there's some magic happening to handle function types and lambdas and it doesn't deal with actual classes," but it handles those too.
There's a note on en.cppreference that says [since c++14]
This constructor does not participate in overload resolution unless f is Callable for argument types Args... and return type R