Требование обработчика для асинхронной операции в boost :: asio - PullRequest
1 голос
/ 19 декабря 2011

В документе boost :: asio указано, что обработчик для 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().Полный список кодов здесь .

Ответы [ 2 ]

2 голосов
/ 20 декабря 2011

Я нашел реальный ответ здесь: http://blog.think -async.com / 2010/04 / bind-illust.html По сути, реальная функция вызывается из оператора вызова функции ().boost :: bind создает объект функции, притворяясь сигнатурой функции, которая должна быть параметром для некоторых других функций.Используя boost :: bind, дополнительная информация может быть передана в обработчик.

1 голос
/ 19 декабря 2011

Эта концепция описана в учебнике по таймеру 3 , так работает bind.

В этом примере аргумент boost::asio::placeholders::error boost::bind() является именованным заполнителем для объекта ошибки, переданного обработчик. При запуске асинхронной операции и при использовании boost::bind(), вы должны указывать только те аргументы, которые соответствуют список параметров обработчика. В уроке Timer.4 вы увидите, что это заполнитель может быть исключен, если параметр не нужен обработчик обратного вызова.

Для вашего вопроса с async_accept параметр error_code передается объекту связанной функции как именованный параметр. Однако вы не обязаны использовать этот параметр. Как показывает вышеприведенный абзац, он может быть исключен. Также могут быть предоставлены дополнительные параметры, это может дать вашему обработчику больше информации об асинхронной операции, которая его инициировала.

...