Как использовать boost :: aio :: async_connect с лямбдой - PullRequest
0 голосов
/ 28 мая 2019

Я хочу высказать, как использовать boost :: aio :: async_connect с лямбда-выражением. Boost версия 1.68

Странно, что я могу использовать std :: bind, но не лямбду. Если я использую std :: bind, это работает. Но когда я использую лямбду, это не помогло, и он сказал: «Требования типа 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)

    );
}

лямбда-версия (не работает)

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);
                                                });
        }


    );
}

Так как же здесь использовать лямбду?

1 Ответ

3 голосов
/ 28 мая 2019

Вы вызываете async_connect с парой итераторов, поэтому ваша лямбда должна соответствовать требованиям обработчика подключения итератора . В качестве второго параметра вы должны передать подключенную конечную точку .

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;
           }
           //...

Чтобы быть в соответствии со ссылкой, вы должны также исправить версию bind. 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_code, ни endpoint не могут быть доступны. (Да, немного странно, что вы не получаете ошибок компилятора при использовании bind, которые сообщают, что требования обработчика не выполняются. Я не знаю, откуда возникло это несоответствие между лямбда и связыванием.)

...