简体   繁体   English

为什么我不能在不移动它们的情况下将 std::optional 与 Boost Asio 套接字一起使用

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM