如何在Lambda上使用boost :: aio :: async_connect

时间:2019-05-28 11:07:05

标签: c++11 boost lambda boost-asio beast-websockets

我想重新说明如何在lambda中使用boost :: aio :: async_connect。 Boost版本1.68

我可以使用std :: bind但不能使用lambda真的很奇怪。 如果我使用std :: bind,它就可以工作。 但是当我使用lambda时,它失败了,并说“未满足IteratorConnectHandler类型要求。

std :: bind版本(有效)

void SslClient::connect(boost::asio::ip::tcp::resolver::results_type results) {
    auto sp = shared_from_this();
    boost::asio::async_connect(ws->next_layer().next_layer(),
        results.begin(),
        results.end(),
        std::bind(
            on_connect,
            std::placeholders::_1)

    );
}

lambda版本(不起作用)

void SslClient::connect(boost::asio::ip::tcp::resolver::results_type results) {
    auto sp = shared_from_this();
    boost::asio::async_connect(ws->next_layer().next_layer(),
        results.begin(),
        results.end(),
            [&, sp](boost::system::error_code ec) {
               if (ec) {
                   return;
               }
               ws->next_layer().async_handshake(boost::asio::ssl::stream_base::client,
                                                [&, sp](boost::system::error_code ec1) {
                                                    handShake(ec);
                                                });
        }


    );
}

那么如何在这里使用lambda?

1 个答案:

答案 0 :(得分:3)

您使用一对迭代器调用async_connect,因此您的lambda应该满足iterator connect handler requirements。作为第二个参数,您必须传递连接的端点

boost::asio::async_connect(ws->next_layer().next_layer(),
    results.begin(),
    results.end(),
        [&, sp](  boost::system::error_code ec,
                  boost::asio::ip::tcp::resolver::iterator it) 
           {
           if (ec) {
               return;
           }
           //...

为与参考保持一致,您还应该修复绑定版本。 on_connect还应将iterator作为第二个参数。

您当前的bind版本可以编译并运行,但是当async_connect发起的异步操作完成时,仅用bind调用error_code创建的函子,您将无法访问endpoint。您可以修改绑定,使其使用on_connect,而无需任何参数。

void on_connect(){}

boost::asio::async_connect(ws->next_layer().next_layer(),
        results.begin(), results.end(), std::bind(on_connect)); // compiles fine

这也可以编译,但是在调用处理程序时,error_codeendpoint都不能访问。 (是的,使用bind时没有得到编译器错误,这说明处理程序的要求未得到满足,这一点有点奇怪。我不知道lambda和bind之间的分歧来自何处。)