I'm currently fiddling with composed operations in boost asio and can't understand why clang seems unable to deduce the return type of my get_executor() method:
template<class Stream, class Resolver, class CompletionToken>
auto resolve_and_connect(
std::string_view host,
std::string_view port,
Stream& stream,
Resolver& resolver,
CompletionToken&& token)
{
using Signature = void(boost::system::error_code);
using Handler = BOOST_ASIO_HANDLER_TYPE(CompletionToken, Signature);
auto initiation = [](auto&& completion_handler, Stream& stream, Resolver& resolver) {
struct intermediate_handler {
Handler m_handler;
Stream& m_stream;
decltype(auto) get_executor() {
return net::get_associated_executor(m_handler, m_stream.get_executor());
}
// using executor_type = decltype(std::declval<intermediate_handler>().get_executor());
};
intermediate_handler{completion_handler, stream};
};
return net::async_initiate<CompletionToken, Signature>(
initiation, token, std::ref(stream), std::ref(resolver)
);
}
Fails with:
error: no viable conversion from returned value of type 'typename associated_executor<(lambda at test.cpp:9:71), executor>::type' (aka 'boost::asio::executor') to function return type 'decltype(auto)'
return net::get_associated_executor(m_handler, m_stream.get_executor());
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Compiled with clang version 10.0.0-4ubuntu1 and -std=c++17.
Notice that namespace net = boost::asio; is implicit in the above code.