C++ 为什么boost::asio::io_服务不使用std::bind编译?
我正在尝试使用C++ 为什么boost::asio::io_服务不使用std::bind编译?,c++,c++11,boost,boost-asio,C++,C++11,Boost,Boost Asio,我正在尝试使用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 &
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;
}
#包括
#包括
#包括
#包括
#包括
#包括
int main(int argc,char*argv[])
{
boost::asio::io_服务ioService;
std::唯一的ptr t;
t、 重置(新std::thread(std::bind(&boost::asio::io_service::run,&ioService));
//t、 重置(新std::thread(boost::bind(&boost::asio::io_service::run,&ioService));
返回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, _Func, _BoundArgs>::type std::bind(_Func&&, _BoundArgs&& ...)
bind(_Func&& __f, _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)));
^
test.cpp:在函数“int main(int,char**)”中:
test.cpp:12:80:错误:调用“bind(,boost::asio::io_service*)”时没有匹配的函数
t、 重置(新std::thread(std::bind(&boost::asio::io_service::run,&ioService));
^
考试。cpp:12:80:注:考生为:
在/usr/include/c++/4.9/memory:79:0中包含的文件中,
来自测试。cpp:2:
/usr/include/c++/4.9/functional:1623:5:注意:模板类型名称std:_Bind_helper::type std::Bind(_Func&,_BoundArgs&&…)
绑定(_Func&&u f,_BoundArgs&&…_参数)
^
/usr/include/c++/4.9/functional:1623:5:注意:模板参数推断/替换失败:
test.cpp:12:80:注意:无法推断模板参数“\u Func”
t、 重置(新std::thread(std::bind(&boost::asio::io_service::run,&ioService));
^
在/usr/include/c++/4.9/memory:79:0中包含的文件中,
来自测试。cpp:2:
/usr/include/c++/4.9/functional:1650:5:注意:模板类型名称std:_Bindres\u helper::type std::bind(_Func&,_BoundArgs&&…)
绑定(_Func&&u f,_BoundArgs&&…_参数)
^
/usr/include/c++/4.9/functional:1650:5:注意:模板参数推断/替换失败:
test.cpp:12:80:注意:无法推断模板参数“\u Result”
t、 重置(新std::thread(std::bind(&boost::asio::io_service::run,&ioService));
^
我遗漏了什么?根据错误消息
boost::asio::io\u service::run
过载,或者成员模板和std::bind()
无法确定要使用哪个过载或实例化。您需要使用这样的方法,在获取地址时可以推断出适当的类型,例如
static_cast<std:size_t (boost::asio::io_service::*)()>(&boost::asio::io_service::run)
理解此错误的关键是
未解析的重载函数类型
部分
这意味着编译器无法确定要使用哪个重载版本的boost::asio::io_service::run
在one中查找有两个版本,您希望使用std::size\u t run()
one。要将此信息传达给编译器,我们需要static\u cast
指向重载变量显式类型的函数指针,这里std:size\t(boost::asio::io\u service::*)()
因此,我们编写了static\u cast(&boost::asio::io\u service::run)
来代替&boost::asio::io\u service::run
完整代码如下所示
boost::asio::io_service ioService;
std::unique_ptr<std::thread> t;
t.reset(new std::thread(std::bind(
static_cast<std::size_t(boost::asio::io_service::*)(void)>(&boost::asio::io_service::run),
&ioService
)));
boost::asio::io\u服务ioService;
std::唯一的ptr t;
t、 重置(新标准::线程(标准::绑定(
静态_cast(&boost::asio::io_service::run),
&丢失服务
)));
Boost Bind支持将智能指针绑定为绑定成员函数的此参数
这是std::bind和boost::bind之间的一个相当大的差异(而且非常可怕)
Boost Asio一直在推广严重依赖于绑定到共享\u指针的模式,其中T
可以是异步IO环境中具有“神奇管理”生存期的任何东西,例如连接
,客户端
,会话
,传输
等
当然,c++11 lambda可以直接支持相同的功能(通过复制捕获共享指针)
例如
错误消息表明std::bind()
无法确定要使用哪个重载:
std::size io_service::run();
std::size io_service::run(boost::system::error_code&);
对于这种特殊情况,Boost.Bind没有问题,但它确实提供了一些故障排除。它建议:
std::bind(
静态_cast(&boost::asio::io_service::run),
&丢失服务);
或使用临时变量:
std::size_t(boost::asio::io_服务::*run)(=&boost::asio::io_服务::run;
std::bind(运行和ioService);
std::bind()
需要显式强制转换,而不是boost::bind()
需要显式强制转换的原因在于实现细节。如果对bind()
的调用的arity没有对绑定的函数类型施加约束,则重载函数将需要显式强制转换
例如,考虑使用可变模板的情况:
template<class F, class... BoundArgs>
unspecified std::bind(F&& f, BoundArgs&&... bound_args);
请注意,当boost::bind()具有以下功能时:
- 如果arity为2,则指向成员函数的指针的arity为0
- 如果arity为3,则指向成员函数的指针的arity为1
因此,在呼叫时:
boost::bind(&boost::asio::io\u service::run,&ioService)
可能匹配的boost::bind()
重载的arity为2,因此指向成员函数的指针必须是arity为0的函数类型。由于io_service::run()
重载集中只有一个函数的算术数为0,因此调用并不含糊。可能重复@DietmarKühl的想法是一样的,但尝试证明我错了。你的铸造工作正常,但是
template<class F, class... BoundArgs>
unspecified std::bind(F&& f, BoundArgs&&... bound_args);