-1

I want to reliaze how to use boost::aio::async_connect with lambda. Boost version 1.68

It's really strange that I could use std::bind but not lambda. If I use std::bind, it work. But when I use lambda, it buillt failed, and said "IteratorConnectHandler type requirements not met.

std::bind version (worked)

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 version (not worked)

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


    );
}

So how to use lambda here?

1
  • 1
    Please post a full error message. Commented May 28, 2019 at 13:50

1 Answer 1

4

You call async_connect with pair of iterators, so your lambda should meet iterator connect handler requirements. As second parameter you have to pass 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;
           }
           //...

To be consistent with reference you should also fix bind version. on_connect should also take iterator as second param.

Your current bind version compiles and works, but when asynchronous operation initiated by async_connect is completed, functor created by bind is called with only error_code, you cannot access endpoint. You can modify bind so that it takes on_connect without any arguments.

void on_connect(){}

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

this also compiles, but when handler is called neither error_code nor endpoint can be accessed. (Yes it is a bit strange that you are not getting compiler errors when using bind which inform that requirements of handler are not fulfilled. I don't know where this disagreement between lambda and bind comes from.)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.