Как использовать boost::aio::async_connect с лямбдой

Я хочу показать, как использовать 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 ответ

Решение

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

Другие вопросы по тегам