boost :: asio中异步操作的处理程序要求

时间:2011-12-19 09:48:23

标签: c++ boost-asio boost-bind

boost::asio document中指定async_accept()的处理程序必须满足以下函数签名:

void accept_handler(
    const boost::system::error_code& ec)
{
  ...
}

但是,在Daytime.3示例中,使用boost :: bind,处理程序可以根据需要指定尽可能多的参数,只要它不超过boost::bind的限制(即9)最多的参数):

class tcp_server
{
public:
  tcp_server(boost::asio::io_service& io_service)
    : acceptor_(io_service, tcp::endpoint(tcp::v4(), 13))
  {
    start_accept();
  }

private:
  void start_accept()
  {
    tcp_connection::pointer new_connection =
      tcp_connection::create(acceptor_.get_io_service());

    acceptor_.async_accept(new_connection->socket(),
        boost::bind(&tcp_server::handle_accept, this, new_connection,
          boost::asio::placeholders::error));
  }

  void handle_accept(tcp_connection::pointer new_connection,
      const boost::system::error_code& error)
  {
    if (!error)
    {
      new_connection->start();
    }

    start_accept();
  }

  tcp::acceptor acceptor_;
};

为什么会这样?我认为即使使用boost::bind,仍然必须匹配确切的函数签名。

请注意handle_accept()功能及其在async_accept()中的使用方式。完整的代码清单为here

2 个答案:

答案 0 :(得分:2)

我在这里找到了真正的答案:http://blog.think-async.com/2010/04/bind-illustrated.html 基本上,实函数被称为函数调用操作符()的底层。 boost :: bind创建一个函数对象,假装是一些其他函数的参数所需的函数签名。使用boost :: bind,可以将附加信息传递给处理程序。

答案 1 :(得分:1)

timer tutorial 3中描述了这个概念,它是bind的工作原理。

  

在此示例中,boost::asio::placeholders::error参数为。{1}}   boost::bind()是传递给的错误对象的命名占位符   处理程序。启动异步操作时,如果使用   boost::bind(),您必须只指定与之匹配的参数   处理程序的参数列表。在教程Timer.4中,您将看到这一点   如果不需要参数,则可以省略占位符   回调处理程序。

具体到async_accept的问题,error_code参数作为命名参数传递给绑定的函数对象。但是,您不需要使用该参数。如上段所示,可能会被省略。还可以提供其他参数,这可以为处理程序提供有关触发它的异步操作的更多信息。