c++ - boost::asio::deadline_timer 绑定(bind)到多态套接字类指针

标签 c++ sockets boost tcp boost-asio

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

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 .另一类asio_socket_https也遵循相同的方案。

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

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

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

提示传递了 5 个参数,而候选人期望有 2 个参数。 我的猜测是 timer.async_wait想将方法绑定(bind)到对象?

  1. 如何将异步计时器正确绑定(bind)到调度操作?
  2. 我是否需要进行嵌套绑定(bind),一次用于异步计时器,一次用于计划作业?

最佳答案

如果你想将引用传递给 bind您需要将它们作为 reference_wapper<> 传递,你可以用 boost::ref(x) 制作或 boost::cref(x) .

如果不这样做,bind call 将尝试复制它们,这当然不能用于不可复制的 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 要求其处理程序能够接受错误代码参数作为其“第一个”未绑定(bind)参数。

这就是为什么您必须指定 boost::placeholders::_1 - 以将 Binder 中的“第一个”参数(由 bind 创建)编码为您类的处理程序方法的第四个参数。

关于c++ - boost::asio::deadline_timer 绑定(bind)到多态套接字类指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36972923/

相关文章:

c++ - OpenGL 窗口未打开

c++ - 使用 Swap 函数对类对象数组进行排序后出现重复条目​​ - C++

c++ - 使用 .mm 文件中的 Objective-C++ 和 C++ 类将 Apple 的 ClassKit 和 swift 类合并到现有应用程序中时出错

c++ - boost::multi_index_container 因 _com_ptr_t 对象而崩溃

c++ - C++程序如何获得debug/release条件编译

java - (套接字)在java程序中pop3命令仅检索一条消息

javascript - 发送到套接字 IO socket.id

c - 伯克利套接字: connect() returns -1 with errno set to ENOENT

c++ - 将 boost::transform_iterator 与非常量仿函数一起使用

c++ - boost 从结构列表派生的结构的序列化