2011-12-19 65 views
1

它在boost::asio document,对于async_accept()处理程序必须满足下列函数签名规定:处理程序要求

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

然而,在Daytime.3例如,使用boost ::绑定,该处理器可以被指定为按需要很多参数,只要不超过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

回答

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(函数对象部分),我想通了。谢谢你的回答,虽然这是正确的,但仍然不够。我想知道为什么'bind'可以使用更少的参数将2个或更多参数函数转换为所需的函数对象/指针。 – Amumu 2011-12-19 19:09:25