在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。
答案 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
参数作为命名参数传递给绑定的函数对象。但是,您不需要使用该参数。如上段所示,可能会被省略。还可以提供其他参数,这可以为处理程序提供有关触发它的异步操作的更多信息。