gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 15:38:28 25 4
gpt4 key购买 nike

我正在尝试使用 std::threadstd::bindboost::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;
}

这是错误:

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

我错过了什么?

最佳答案

错误消息表明 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()的参数不限制被绑定(bind)的函数类型,那么重载函数将需要显式转换。

例如,考虑使用可变参数模板的情况:

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() 的调用的数量。对被绑定(bind)函数的元数施加约束。它的界面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 T, 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()作为潜在匹配的重载具有 2 的元数,因此指向成员函数的指针必须是一种具有 0 元数的函数类型。因为在 io_service::run() 的集合中只有一个函数。重载的元数为 0,调用没有歧义。

关于c++ - 为什么 boost::asio::io_service 不能用 std::bind 编译?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28794203/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com