Repeated std::move on an boost::asio socket object in C++11

As documented in tcp::socket reference:

Following the move, the moved-from object is in the same state as if constructed using the basic_stream_socket(io_service&) constructor.

The above means that you can move the original socket object from server to session as many times as you need.


Move semantics can be thought of as passing ownership of resources. Resource Acquisition Is Instantiation (RAII) is the concept of assigning ownership of resources at the time of object construction and the releasing of those resources at destruction. Move semantics allow for the transfer of ownership of resources at other times besides construction and destruction.

In this case, the object (server::socket_) is the recipient of a transfer of ownership of the OS socket resource from server::acceptor_. That transfer occurs at some point after async_accept() returns, when a client connects. The newly connected socket resources are moved into socket_, and the callback lambda function is called. During the lambda, the socket resources are moved into session::socket_. Server::socket_ only owned the resource for a fraction of a microsecond.

Move semantics allow RAII classes to exist in the twilight state of not owning any resources. Think of a unique_ptr after a call to release (it refers to no memory). The server::socket_ after the move out still has space to hold a resource, but for the moment it owns nothing.

The last thing the lambda function does is call do_accept, which calls async_accept() again. A reference to socket_ is passed in. When another client connects at some point in the future, async_accept() will transfer ownership of a newly connected OS socket there.