Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 423
Ilya Kobelevskiy Avatar asked Aug 15 '15 02:08

Ilya Kobelevskiy


1 Answers

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);
like image 156
StenSoft Avatar answered Sep 27 '22 21:09

StenSoft