但是,当创建新线程时,它不会编译,当我使用std :: bind.另一方面,当我切换到boost :: bind一切都很好.
以下是代码:
#include <iostream> #include <memory> #include <thread> #include <functional> #include <boost/asio.hpp> #include <boost/bind.hpp> int main(int argc,char* argv[]) { boost::asio::io_service ioService; std::unique_ptr<std::thread> t; t.reset(new std::thread(std::bind(&boost::asio::io_service::run,&ioService))); //t.reset(new std::thread(boost::bind(&boost::asio::io_service::run,&ioService))); return 0; }
这是错误:
test.cpp: In function ‘int main(int,char**)’: test.cpp:12:80: error: no matching function for call to ‘bind(<unresolved overloaded function type>,boost::asio::io_service*)’ t.reset(new std::thread(std::bind(&boost::asio::io_service::run,&ioService))); ^ test.cpp:12:80: note: candidates are: In file included from /usr/include/c++/4.9/memory:79:0,from test.cpp:2: /usr/include/c++/4.9/functional:1623:5: note: template<class _Func,class ... _BoundArgs> typename std::_Bind_helper<std::__or_<std::is_integral<typename std::decay<_Tp>::type>,std::is_enum<typename std::decay<_Tp>::type> >::value,_Func,_BoundArgs ...>::type std::bind(_Func&&,_BoundArgs&& ...) bind(_Func&& __f,_BoundArgs&&... __args) ^ /usr/include/c++/4.9/functional:1623:5: note: template argument deduction/substitution Failed: test.cpp:12:80: note: couldn't deduce template parameter ‘_Func’ t.reset(new std::thread(std::bind(&boost::asio::io_service::run,&ioService))); ^ In file included from /usr/include/c++/4.9/memory:79:0,from test.cpp:2: /usr/include/c++/4.9/functional:1650:5: note: template<class _Result,class _Func,class ... _BoundArgs> typename std::_Bindres_helper<_Result,_BoundArgs>::type std::bind(_Func&&,_BoundArgs&&... __args) ^ /usr/include/c++/4.9/functional:1650:5: note: template argument deduction/substitution Failed: test.cpp:12:80: note: couldn't deduce template parameter ‘_Result’ t.reset(new std::thread(std::bind(&boost::asio::io_service::run,&ioService))); ^
我失踪了什么
解决方法
io_service::run()
重载:
std::size io_service::run(); std::size io_service::run(boost::system::error_code&);
对于这种特殊情况,Boost.Bind没有问题,但它确实为binding an overloaded functions提供了一些故障排除.它建议要么转换:
std::bind( static_cast<std::size_t (boost::asio::io_service::*)()>(&boost::asio::io_service::run),&ioService);
或使用临时变量:
std::size_t (boost::asio::io_service::*run)() = &boost::asio::io_service::run; std::bind(run,&ioService);
std :: bind()而不是boost :: bind()需要显式转换的原因是由于实现细节.如果对bind()的调用的arity不对绑定的函数的类型施加约束,那么重载函数将需要显式转换.
例如,考虑使用可变模板的情况:
template<class F,class... BoundArgs> unspecified std::bind(F&& f,BoundArgs&&... bound_args);
当选择最匹配的std :: bind()重载时,对std :: bind()的调用的无关性对F没有限制.F可以是以下任一项:
> std :: size_t(boost :: asio :: io_service :: *)()
> std :: size_t(boost :: asio :: io_service :: *)(boost :: system :: error_code&)
表达式& boost :: asio :: io_service :: run()是不明确的.
另一方面,Boost.Bind是通过重载函数实现的,其中对boost :: bind()的调用的特性对绑定的函数的arity进行了限制.其界面synopsis列出了以下值得注意的重载:
// 2 args: member-to-function (arity:0),instance template <class R,class T,class A1> unspecified bind(R (T::*f)(),A1 a1); // 3 args: member-to-function (arity:1),instance,arg1 template <class R,class B1,class A1,class A2> unspecified bind(R (T::*f)(B1),A1 a1,A2 a2);
注意,当boost :: bind()有:
>一个2,这个指针到成员的函数具有0的概率
>一个3,指向成员的函数具有1的概率
因此,当呼叫:
boost::bind(&boost::asio::io_service::run,&ioService)
boost :: bind()重载是潜在的匹配,它的arity为2,因此指针到成员函数必须是一个arity为0的函数类型.由于io_service ::的集合中只有一个函数run()重载的arity为0,调用并不模糊.