c – 为什么boost :: asio :: io_service不能用std :: bind编译?

前端之家收集整理的这篇文章主要介绍了c – 为什么boost :: asio :: io_service不能用std :: bind编译?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在使用g 4.9.1(-std = c 11)来编译具​​有std :: thread,std :: bind和boost :: asio的简单测试程序.

但是,当创建新线程时,它不会编译,当我使用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)));
                                                                            ^

我失踪了什么

解决方法

错误信息表明std :: bind()无法确定要使用哪个 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,调用并不模糊.

猜你在找的C&C++相关文章