When move support is available (via rvalue references), Asio allows move construction and assignment of sockets, serial ports, POSIX descriptors and Windows handles.
Move support allows you to write code like:
tcp::socket make_socket(io_context& i) { tcp::socket s(i); ... std::move(s); }
or:
class connection : public enable_shared_from_this<connection> { private: tcp::socket local_socket; ... public: connection(tcp::socket&& s) : local_socket(std::move(s)) {} ... }; ... class server { private: tcp::acceptor acceptor_; ... void handle_accept(error_code ec, tcp::socket socket) { if (!ec) std::make_shared<connection>(std::move(socket))->go(); acceptor_.async_accept(...); } ... };
as well as:
std::vector<tcp::socket> sockets; sockets.push_back(tcp::socket(...));
A word of warning: There is nothing stopping you from moving these objects while there are pending asynchronous operations, but it is unlikely to be a good idea to do so. In particular, composed operations like async_read() store a reference to the stream object. Moving during the composed operation means that the composed operation may attempt to access a moved-from object.
Move support is automatically enabled for g++
4.5 and
later, when the -std=c++0x
or -std=gnu++0x
compiler options are used. It may be disabled by defining ASIO_DISABLE_MOVE
, or explicitly enabled
for other compilers by defining ASIO_HAS_MOVE
.
Note that these macros also affect the availability of movable
handlers.