I'm creating a simple network game in c .
I have a server class where a single socket is stored for usage. The socket is not known at the creation of the class, so I've chosen to use a std::optional<tcp::socket>
(is this the correct way or is there a better one?) which is initialized to std::nullopt
and later a socket will have a socket stored inside.
I've seen that, since it only has a rvalue copy operator, I have to move the socket before assigning it, in this way:
std::optional<tcp::socket> optSocket(std::nullopt);
....
optSocket = std::move(mySocket);
On the other hand, I've seen that if I use a simple "std::string" variable (so not a primitive type) I don't need to move it and I can simply do a copy assignment:
std::optional<std::string> optString(std::nullopt);
....
optString = myString;
While, if I try to do the same with a socket, it gives me the following error:
No viable overloaded '='
candidate template ignored: requirement '__and_v<std::__not_<std::is_same<std::optional<boost::asio::basic_stream_socket<boost::asio
::ip::tcp, boost::asio::any_io_executor>>,
boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost:...
candidate template ignored: could not match 'optional' against 'basic_stream_socket'
candidate template ignored: could not match 'optional' against 'basic_stream_socket'
Why is there a difference between the two types, and why do i need to move the socket (or any other object to pass it to an std::optional)? Wouldn't it be better to have both a copy and move assignment?
Thank you in advance!
CodePudding user response:
Simply put, sockets aren't copyable because it's not clear what a copy of a socket would be. When the remote end sends data which socket instance would receive that data; the original or the copy? What happens when you close the original what should happen to the copy? You could design a socket
class that acts as a shared handle to a socket instead of representing the socket itself, but that would go against the general design theory that most C objects follow. That's what something like std::shared_ptr
is for.
Something as simple as a string doesn't have most of these sorts of concerns. It's fairly clear what it means to make a copy of a string: you just copy the bytes that represent the characters in the string.