Hi everyone,

as a long time asio user I often had needs to wrap up repeating patterns of async calls for re-use. Normally I went for some kind of specialized object that wraps smaller pieces but I recently came across a series of examples which try to explain how own composed operations may be created. 

Now, looking at the examples they are of course way over my head but since own composed operations would be very much exactly what I need I thought I'd give it a shot. But as I now look at this example here: https://www.boost.org/doc/libs/1_71_0/doc/html/boost_asio/example/cpp11/operations/composed_8.cpp I notice something that I hope somebody can explain.

In the coroutine implementation it says:
delay_timer_->expires_after(std::chrono::seconds(1));
yield delay_timer_->async_wait(std::move(self));
if (error)
    break;

yield boost::asio::async_write(socket_,
    boost::asio::buffer(*encoded_message_), std::move(self));
I'm puzzled about the double std::move() of self. In the comments above it says that self is a reference to an intermediate completion handler. How can this be moved twice?
Can anyone give me hint about what this means?

I would also appreciate any hints in general about own composed operations. Perhaps there are other approaches that are a bit less intimidating?

Cheers,
Stephan