Home > Mobile >  Why can't I use std::optional with Boost Asio sockets without moving them
Why can't I use std::optional with Boost Asio sockets without moving them

Time:06-14

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.

  • Related