2011-12-19 3 views
1

Указан в boost::asio document, что обработчик async_accept() должен удовлетворять следующую сигнатуру функции:Handler требования асинхронной операции в повышении :: ASIO

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

Однако в Daytime.3 например, с помощью наддува :: связывай обработчик может быть определен как много параметров, по желанию, пока он не превышает предел 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() funciton и как он используется в async_accept(). Полный список кодов - here.

ответ

1

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

1

Эта концепция описана в timer tutorial 3, вот как работает bind.

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

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

+0

Прочитав внимательно это руководство: http://en.highscore.de/cpp/boost/index.html (Function Object part), я понял. Спасибо за ответ, хотя он правильный, но все же недостаточный. Мне было интересно, почему 'bind' может включить 2 или более параметров в требуемый объект/указатель функции с меньшими параметрами. – Amumu

Смежные вопросы