I have two overloads of the foo function that take different std::function , which leads to an ambiguity problem for the latter when used with the result of std::bind . I do not 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 the bind function, I get an ambiguity error
foo(std::bind(ret_int));
With 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 works
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 constructor std::function
template< class F > function( F f );
It would be reasonable to me that any function with several overloads on different types of std::function should have ambiguity, but this is only a problem with calling bind. Then I thought: โMaybe there is some magic to handle function types and lambda, and it does not concern real classesโ, but it also processes them.
There is a note to en.cppreference here that says [since C ++ 14]
This constructor is not involved in overload resolution unless f is Callable for the argument types Args ... and return type R
source share