boost::asio::deadline_timer绑定到多态套接字类指针

boost::asio::deadline_timer binding to a polymorphic socket class pointer

本文关键字:多态 套接字 指针 timer asio deadline boost 绑定      更新时间:2023-10-16

我的方案(或多或少)如下:

asio_socket是具有单一纯虚拟方法的abc:

virtual void schedule(
                      boost::asio::ip::tcp::resolver::query &,
                      boost::asio::ip::tcp::resolver &,
                      boost::asio::io_service &
                     ) = 0;

另一个类asio_socket_http继承自它,也继承自另一个asio_helper。另一类CCD_ 4也遵循相同的方案。

asio_socket_http实现了用于http连接的asio_async处理程序。

其他类(定义特定的URI/URL相关操作)继承自asio_socket_httpasio_socket_https

存在一个作业调度程序:

void run_job(const std::shared_ptr<asio_socket> job);

在内部,它所做的只是:

void run_job(const std::shared_ptr<asio_socket> job)
{
    boost::asio::io_service io;
    boost::asio::ip::tcp::resolver resolver(io);
    job->schedule(query_, resolver, io);
    io.run();
}

我想添加一个截止日期计时器,它将处理asio:的异步特性

void run_job(const std::shared_ptr<asio_socket> job)
{
    boost::asio::io_service io;
    boost::asio::ip::tcp::resolver resolver(io);
    boost::asio::deadline_timer timer(io, boost::posix_time::seconds(3)); 
    timer.async_wait(boost::bind(&asio_socket::schedule, *job));
    // I also have to bind the 3 params: query_, resolver, io
    io.run();
}

这样做,我得到template argument deduction/substitution failed:实际误差为:

‘void (rapp::cloud::asio_socket::*)(boost::asio::ip::basic_resolver<boost::asio::ip::tcp>::query&, boost::asio::ip::tcp::resolver&, boost::asio::io_service&) {aka void (rapp::cloud::asio_socket::*)(boost::asio::ip::basic_resolver_query<boost::asio::ip::tcp>&, boost::asio::ip::basic_resolver<boost::asio::ip::tcp>&, boost::asio::io_service&)}’ is not derived from ‘boost::type<R>’ timer.async_wait(boost::bind(&asio_socket::schedule, *job));

如何绑定(多态)共享指针job的方法schedule,同时绑定参数?尝试:

timer.async_wait(boost::bind(&asio_socket::schedule, *job, _1, _2, _3)(&query_, &resolver, &io))

抱怨通过了5个论点,而候选人期望通过2个论点。我的猜测是timer.async_wait想要将一个方法绑定到一个对象?

  1. 如何将异步计时器正确绑定到计划操作
  2. 我需要做嵌套绑定吗?一次用于异步定时器,一次用于计划作业

如果要将引用传递到bind,则需要将它们作为reference_wapper<>传递,可以使用boost::ref(x)boost::cref(x)进行传递。

如果不这样做,bind调用将尝试复制它们,这当然不能用于不可复制的asio对象。

像这样的东西应该起作用:

timer.async_wait(boost::bind(&asio_socket::schedule, 
                job,  // should bind to a shared_ptr just fine 
                boost::ref(query_),
                boost:;ref(resolver),
                boost::ref(io),
                boost::placeholders::_1);

时间表需要以下签名:

(boost::asio::ip::tcp::resolver::query &,
 boost::asio::ip::tcp::resolver &,
 boost::asio::io_service &,
 const boost::system::error_code& ec)

因为async_wait要求其处理程序能够接受错误代码参数作为其"第一个"未绑定参数。

这就是为什么必须指定boost::placeholder::_1-将绑定器中的"first"参数(由绑定创建)封送到类的处理程序方法的第四个参数。