ecl*_*pse 11 c++ boost boost-asio c++11
我正在尝试编译简单的测试程序std::thread,std::bind并boost::asio使用g++4.9.1(-std=c++11).
但是,在创建新线程时,它在我使用时不会编译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;
}
Run Code Online (Sandbox Code Playgroud)
这是错误:
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)));
^
Run Code Online (Sandbox Code Playgroud)
我错过了什么?
Tan*_*ury 13
错误消息表明std::bind()无法确定io_service::run()要使用的重载:
std::size io_service::run();
std::size io_service::run(boost::system::error_code&);
Run Code Online (Sandbox Code Playgroud)
对于这种特殊情况,Boost.Bind没有问题,但它确实为绑定重载函数提供了一些故障排除.它建议铸造:
std::bind(
static_cast<std::size_t (boost::asio::io_service::*)()>(&boost::asio::io_service::run),
&ioService);
Run Code Online (Sandbox Code Playgroud)
或使用临时变量:
std::size_t (boost::asio::io_service::*run)() = &boost::asio::io_service::run;
std::bind(run, &ioService);
Run Code Online (Sandbox Code Playgroud)
为什么需要为显式类型转换的原因std::bind(),但不能boost::bind()是由于实施细则.如果调用的arity bind()没有对被绑定的函数类型设置约束,则重载函数将需要显式转换.
例如,考虑使用可变参数模板的情况:
template<class F, class... BoundArgs>
unspecified std::bind(F&& f, BoundArgs&&... bound_args);
Run Code Online (Sandbox Code Playgroud)
当选择最佳匹配的std::bind()重载时,调用的arity对其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对被绑定函数的arity设置了约束.其界面概要列出了以下值得注意的重载:
// 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 T, class B1, class A1, class A2>
unspecified bind(R (T::*f)(B1), A1 a1, A2 a2);
Run Code Online (Sandbox Code Playgroud)
注意,当boost::bind()有:
因此,在致电时:
boost::bind(&boost::asio::io_service::run, &ioService)
Run Code Online (Sandbox Code Playgroud)
boost::bind()潜在匹配的重载具有2的arity,因此指向成员的函数必须是一个arity为0的函数类型.因为只有io_service::run()过载集合中的单个函数的arity为0,所以调用不是暧昧.
Die*_*ühl 10
基于错误消息boost::asio::io_service::run是重载或成员模板,std::bind()并且无法确定它要使用哪个重载或实例化.您需要使用这样的东西,在获取地址时推断出适当的类型,例如,
static_cast<std:size_t (boost::asio::io_service::*)()>(&boost::asio::io_service::run)
Run Code Online (Sandbox Code Playgroud)
关键问题是将boost::asio::io_service::run结果的地址作为成员函数的两个选择,但在获取地址时,没有任何方法可以确定使用哪个.只有在使用成员函数时,才会明确表示不使用其他参数的版本.但是,address-of运算符不会产生过载集.
要推断出需要哪个重载,std::bind()需要提供一个自身的重载,它具有适当的类型作为其第一个参数.但是,我认为它无法确定应该是什么类型.我不知道它是如何实际使用的std::boost::bind()!我可以想像,boost::bind()有成员函数重载专用不带参数,可能的话,一个boost::error_code,但我实在不明白怎么会有用的.
但是,使用lambda函数可能更容易:
std::thread t([&](){ ioService.run(); });
t.join(); // without a joining or detaching terminate() is called
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2909 次 |
| 最近记录: |