如何使用 boost::aio::async_connect 和 lambda

How to use boost::aio::async_connect with lambda

我想了解如何将 boost::aio::async_connect 与 lambda 一起使用。 提升版本 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呢?

你打电话给async_connect with pair of iterators, so your lambda should meet iterator connect handler requirements。作为第二个参数,您必须传递 connected endpoint.

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 发起的异步操作完成时,仅 error_code 调用 bind 创建的仿函数,您无法访问 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 之间的分歧从何而来。)