Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么boost::asio::io_服务不使用std::bind编译?_C++_C++11_Boost_Boost Asio - Fatal编程技术网

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);