3

我在想这将是直截了当的,但我必须遗漏一些关键的东西,因此错误 =O。我在源文件中收到“使用已删除功能”错误。

无论如何,我知道我的头文件已正确连接,因为它已在整个源文件中正确调用,除了这一行,源代码片段是唯一需要评估的地方。

标头源代码

using boost::asio::ip::tcp;
tcp::acceptor mAcceptor;
std::map<std::string, tcp::socket> mSockets;

源文件代码

tcp::socket socket(ioService);
mAcceptor.accept(socket);
std::string myKey = "Socket"; // Didn't add actual key string creation
mSockets[myKey] = socket;

错误

错误:使用删除函数'boost::asio::basic_stream_socket& boost::asio::basic_stream_socket::operator{const boost::asio::basic_stream_socket&)' mSockets[myKey] = socket;

继续说:被隐式声明为已删除,因为'boost::asio::basic_stream_socket'声明了一个移动构造函数或移动赋值运算符类basic_stream_socket。

更新

@Radosław Cybulski 建议尝试 std::move(socket) ,这消除了很大一部分错误,但现在导致。

错误 #2

'boost::asio::basic_stream_socket::basic_stream_socket()' 秒(std::forward<_Args2>(std::get<_Indexes2>(_tuple2))...)

4

3 回答 3

4

尝试:

mSockets.insert({ myKey, std::move(socket) });

复制操作符被删除,因为没有复制套接字的好方法。我的意思是,你连接到某个东西,然后复制,现在呢?您可以同时发送两份副本,只发送一份(哪一份?),其他的?所以它被删除了,如果你想传递它,使用移动构造函数/赋值和std::move.

编辑:由于空构造函数也被删除,你不能使用mSockets[key] = .... 所以我们必须依赖insert/ emplace。为什么?operator[]在地图上需要存在值类型的默认构造函数。我不知道为什么,但就是这样。

于 2019-06-17T15:42:15.443 回答
3

您不能使用mapwithboost::asio::ip::tcp::socket作为值,因为map要求其值是默认可构造的(例如,在map::operator[]调用时会创建默认构造的实例),asio::ip::tcp::socket但不能满足它,因为它的 ctor 至少需要将io_context对象作为参数。

使用shared_ptrorunique_ptr作为 map 的值。

于 2019-06-17T15:50:48.703 回答
0

套接字不能是默认构造的,并且您使用的运算符要求它就是这样(使用默认分配器时)。

T& std::map::operator[](const Key& key)

[...] value_type必须是EmplaceConstructible来自
std::piecewise_construct, std::forward_as_tuple(key), std::tuple<>(). 当使用默认分配器时,这意味着它 key_type必须是 CopyConstructible 并且mapped_type必须是 DefaultConstructible

但是,您可以使用emplace()套接字并将其移动到std::pair<std::string, tcp::socket>正在构建的地方:

auto [it, inserted] = mSockets.emplace(myKey, std::move(socket));

这将使用构造函数而不是移动构造套接字(正如您所注意到的那样,它不存在)。tcp::socket(tcp::socket&&)tcp::socket()

于 2019-06-17T17:39:35.707 回答