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.
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.