[英]Why can't I use std::optional with Boost Asio sockets without moving them
I'm creating a simple network game in c++.我正在用 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.在创建类时套接字是未知的,所以我选择使用一个
std::optional<tcp::socket>
(这是正确的方法还是有更好的方法?),它被初始化为std::nullopt
和稍后的套接字将在其中存储一个套接字。 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::string”变量(所以不是原始类型),我不需要移动它,我可以简单地进行复制分配:
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)?为什么这两种类型之间存在差异,为什么我需要移动套接字(或任何其他对象以将其传递给 std::optional)? Wouldn't it be better to have both a copy and move assignment?
拥有副本和移动任务不是更好吗?
Thank you in advance!先感谢您!
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.您可以设计一个
socket
类来充当套接字的共享句柄,而不是表示套接字本身,但这将违背大多数 C++ 对象遵循的一般设计理论。 That's what something like std::shared_ptr
is for.这就是
std::shared_ptr
之类的东西。
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.
复制字符串意味着什么是相当清楚的:您只需复制代表字符串中字符的字节。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.