将boost套接字放入std :: map

时间:2019-06-17 15:39:28

标签: c++ c++11 boost

我当时想这很简单,但是我必须错过一些关键的东西,因此错误= 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] =套接字;

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

更新

@RadosławCybulski建议尝试std :: move(socket),这样可以消除大部分错误,但现在会导致错误。

错误#2

'boost :: asio :: basic_stream_socket :: basic_stream_socket()'second(std :: forward <_Args2>(std :: get <_Indexes2>(_ tuple2))...)

3 个答案:

答案 0 :(得分:4)

尝试:

x

复制操作符被删除,因为没有好的方法可以复制套接字。我的意思是,您连接到某个东西,然后复制,现在怎么办?您可以同时发送两份,只有一份(哪一个?),还有其他东西吗?因此它已被删除,如果您想传递它,请使用move构造器/赋值和override

编辑:由于空的构造函数也被删除,因此不能使用mSockets.insert({ myKey, std::move(socket) }); 。因此,我们必须依靠std::move / mSockets[key] = ...。为什么?地图上的insert需要存在值类型的默认构造函数。我不知道为什么,但是就在这里。

答案 1 :(得分:3)

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

使用shared_ptrunique_ptr作为地图的值。

答案 2 :(得分:0)

不能默认构造该套接字,并且您正在使用的运算符要求它只是那个(使用默认分配器时)。

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

  

[...] value_type必须是来自{br3的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()(您所注意到的不存在)move-construct套接字。