为什么 std::bind 无法解析具有多个参数的函数重载?
Why std::bind cannot resolve function overloads with multiple arguments?
考虑以下示例:
#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;
}
它按原样编译和运行良好(https://ideone.com/fork/2SywE2),但取消注释注释行会导致编译器错误:
prog.cpp: 在函数中 'int main()':
prog.cpp:10:48: 错误:没有匹配函数来调用 'bind(, int, const std::_Placeholder<1>&)'
auto functor = std::bind(&f,1,placeholders::_1);
^
在 prog.cpp:2:0 包含的文件中:
/usr/include/c++/5/functional:1462:5: 注意:候选:模板类型名 std::_Bind_helper::value, _Func, _BoundArgs ...>::type std::bind(_Func&&, _BoundArgs&& ... )
绑定(_Func&& __f, _BoundArgs&&... __args)
^
/usr/include/c++/5/functional:1462:5: 注意:模板参数 deduction/substitution 失败:
prog.cpp:10:48: 注意:无法推断模板参数“_Func”
auto functor = std::bind(&f,1,placeholders::_1);
^
在 prog.cpp:2:0 包含的文件中:
/usr/include/c++/5/functional:1490:5: 注意:候选:模板类型名 std::_Bindres_helper<_Result, _Func, _BoundArgs>::type std::bind(_Func&&, _BoundArgs&& ...)
绑定(_Func&& __f, _BoundArgs&&... __args)
^
/usr/include/c++/5/functional:1490:5: 注意:模板参数 deduction/substitution 失败:
prog.cpp:10:48: 注意:无法推断模板参数“_Result”
自动仿函数 = std::bind(&f,1,placeholders::_1);
如果存在多个重载,为什么 std::bind 无法解析模板参数,因为重载具有不同数量的输入参数,调用 bind 意味着输入参数的数量为 2。
当 C++ 编译器看到对 std::bind(&f,1,placeholders::_1)
的调用时,它不知道参数之间的任何关系。仅当模板被实例化时,关系才可见。要实例化它,编译器需要模板参数。但是 &f
是一个重载函数,因此它没有定义的类型。因此 C++ 编译器无法实例化模板,因此即使在看到任何关系之前编译也会失败。
您可以通过明确指定类型来解决此问题:
std::bind(static_cast<void(*)(int,int)>(&f),1,placeholders::_1);
考虑以下示例:
#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;
}
它按原样编译和运行良好(https://ideone.com/fork/2SywE2),但取消注释注释行会导致编译器错误:
prog.cpp: 在函数中 'int main()': prog.cpp:10:48: 错误:没有匹配函数来调用 'bind(, int, const std::_Placeholder<1>&)' auto functor = std::bind(&f,1,placeholders::_1); ^ 在 prog.cpp:2:0 包含的文件中: /usr/include/c++/5/functional:1462:5: 注意:候选:模板类型名 std::_Bind_helper::value, _Func, _BoundArgs ...>::type std::bind(_Func&&, _BoundArgs&& ... ) 绑定(_Func&& __f, _BoundArgs&&... __args) ^ /usr/include/c++/5/functional:1462:5: 注意:模板参数 deduction/substitution 失败: prog.cpp:10:48: 注意:无法推断模板参数“_Func” auto functor = std::bind(&f,1,placeholders::_1); ^ 在 prog.cpp:2:0 包含的文件中: /usr/include/c++/5/functional:1490:5: 注意:候选:模板类型名 std::_Bindres_helper<_Result, _Func, _BoundArgs>::type std::bind(_Func&&, _BoundArgs&& ...) 绑定(_Func&& __f, _BoundArgs&&... __args) ^ /usr/include/c++/5/functional:1490:5: 注意:模板参数 deduction/substitution 失败: prog.cpp:10:48: 注意:无法推断模板参数“_Result” 自动仿函数 = std::bind(&f,1,placeholders::_1);
如果存在多个重载,为什么 std::bind 无法解析模板参数,因为重载具有不同数量的输入参数,调用 bind 意味着输入参数的数量为 2。
当 C++ 编译器看到对 std::bind(&f,1,placeholders::_1)
的调用时,它不知道参数之间的任何关系。仅当模板被实例化时,关系才可见。要实例化它,编译器需要模板参数。但是 &f
是一个重载函数,因此它没有定义的类型。因此 C++ 编译器无法实例化模板,因此即使在看到任何关系之前编译也会失败。
您可以通过明确指定类型来解决此问题:
std::bind(static_cast<void(*)(int,int)>(&f),1,placeholders::_1);