Ilya Kobelevskiy
Ilya Kobelevskiy

Reputation: 5345

Why std::bind cannot resolve function overloads with multiple arguments?

Consider following example:

#include <iostream>
#include <functional>

using namespace std;

void f(int x,int y) {}
// void f(int x) {} // if this line is uncommented, code does not compile.

int main() {
    auto functor = std::bind(&f,1,placeholders::_1);
    cout << "works!" << endl;
    return 0;
}

It compiles and runs fine as is (https://ideone.com/fork/2SywE2), but uncommenting the commented line leads to compiler error:

prog.cpp: In function 'int main()': prog.cpp:10:48: error: no matching function for call to 'bind(, int, const std::_Placeholder<1>&)' auto functor = std::bind(&f,1,placeholders::_1); ^ In file included from prog.cpp:2:0: /usr/include/c++/5/functional:1462:5: note: candidate: template typename std::_Bind_helper::value, _Func, _BoundArgs ...>::type std::bind(_Func&&, _BoundArgs&& ...) bind(_Func&& __f, _BoundArgs&&... __args) ^ /usr/include/c++/5/functional:1462:5: note: template argument deduction/substitution failed: prog.cpp:10:48: note: couldn't deduce template parameter '_Func' auto functor = std::bind(&f,1,placeholders::_1); ^ In file included from prog.cpp:2:0: /usr/include/c++/5/functional:1490:5: note: candidate: template typename std::_Bindres_helper<_Result, _Func, _BoundArgs>::type std::bind(_Func&&, _BoundArgs&& ...) bind(_Func&& __f, _BoundArgs&&... __args) ^ /usr/include/c++/5/functional:1490:5: note: template argument deduction/substitution failed: prog.cpp:10:48: note: couldn't deduce template parameter '_Result' auto functor = std::bind(&f,1,placeholders::_1);

Why std::bind cannot resolve template arguments if more than one overload is present, as overloads have different numebr of input arguments, and call to bind implies that number of input arguments is 2.

Upvotes: 8

Views: 2690

Answers (1)

StenSoft
StenSoft

Reputation: 9609

When C++ compilers sees call to std::bind(&f,1,placeholders::_1), it does not know any relations between the parameters. The relations are visible only when the template is instantiated. To instantiate it, the compiler needs template parameters. But &f is an overloaded function and so it does not have defined type. Therefore the C++ compiler cannot instantiate the template and so compilation fails even before any relations can be seen.

You can workaround this by explicitely specifying the type:

std::bind(static_cast<void(*)(int,int)>(&f),1,placeholders::_1);

Upvotes: 8

Related Questions