尝试在Visual C++ 2015中编译它时
auto worker = std::bind(&boost::asio::io_service::run, &(this->service));
我收到错误:
error C2783: 'std::_Binder<_Ret,_Fx,_Types...> std::bind(_Fx &&,_Types &&...)': could not deduce template argument for '_Ret'
note: see declaration of 'std::bind'
error C2783: 'std::_Binder<_Ret,_Fx,_Types...> std::bind(_Fx &&,_Types &&...)': could not deduce template argument for '_Fx'
note: see declaration of 'std::bind'
error C2783: 'std::_Binder<std::_Unforced,_Fx,_Types...> std::bind(_Fx &&,_Types &&...)': could not deduce template argument for '_Fx'
note: see declaration of 'std::bind'
此外,IntelliSense还抱怨:
cannot determine which instance of overloaded function "boost::asio::io_service::run" is intended
我看到有 2 个超载的boost::asio::io_service::run
.但是如何指定要使用哪一个呢?
有了boost::bind
代码就可以很好地编译:
auto worker = boost::bind(&boost::asio::io_service::run, &(this->service));
由于 boost::asio::io_service::run
有两个重载,因此在将其用作函数指针(1) 时需要指定使用哪个重载。这需要通过将其转换为正确的函数签名来完成:
static_cast<std::size_t(boost::asio::io_service::*)()>(&boost::asio::io_service::run)
由于这看起来很糟糕,我建议使用 lambda 而不是绑定表达式。在 lambda 内部,会发生正常的重载解析,因此您无需显式指定重载:
auto worker = [this]{ return service.run(); };
(1)问题是std::bind
通过不受限制的模板参数获取函数,因此适用模板类型推导规则而不是重载解析。C++无法确定此处应_Fx
的类型,因为您传递了未指定类型的内容。即使有一个技巧,当使用绑定参数将被传递给函数的事实时,C++可以尝试解决重载,请注意,实际上这里两个重载都是可能的:带有boost::system::error_code & ec
的重载将简单地不被绑定和"柯里化"(指定该参数的值会延迟到调用worker
时)。