Search code examples
c++boost-asioboost-bind

Handler requirement for Asynchronous Operation in boost::asio


It is specified in boost::asio document that a handler for async_accept() must satisfy the following function signature:

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

However, in the Daytime.3 example, using boost::bind, the handler can be specified as much parameter as desired, as long as it does not exceed the limit of boost::bind (which is 9 arguments at maximum):

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_;
};

Why is that possible? I thought even with boost::bind, the exact function signature still has to be matched.

Notice the handle_accept() funciton and how it is used in async_accept(). The full code listing is here.


Solution

  • I found the real answer here: http://blog.think-async.com/2010/04/bind-illustrated.html Basically, the real function is called underlying the function call operator (). boost::bind creates a function object, pretend to be the function signature required to be a parameter for some other functions. Using boost::bind, additional information can be passed into the handler.