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?
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.)