Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将boost套接字放入std::map_C++_C++11_Boost - Fatal编程技术网

C++ 将boost套接字放入std::map

C++ 将boost套接字放入std::map,c++,c++11,boost,C++,C++11,Boost,我认为这将是直截了当的,但我必须错过一些关键的东西,因此错误=O。 我在源文件中收到“使用已删除函数”错误 无论如何,我知道我的头文件连接正确,因为它在整个源文件中被正确调用,除了这一行之外,源代码片段是唯一需要评估的地方 标题源代码 using boost::asio::ip::tcp; tcp::acceptor mAcceptor; std::map<std::string, tcp::socket> mSockets; tcp::socket socket(ioServic

我认为这将是直截了当的,但我必须错过一些关键的东西,因此错误=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”声明了移动构造函数或移动赋值运算符类basic_stream_socket

更新

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;
@Radosław Cybulski建议尝试std::move(socket),这消除了很大一部分错误,但这现在导致了错误

错误#2

'boost::asio::basic_stream_socket::basic_stream_socket()'秒(std::forward(std::get(_tuple2)))

尝试:

mSockets.insert({ myKey, std::move(socket) });
复制操作符被删除了,因为没有复制套接字的好方法。我的意思是,您连接到某个对象,然后复制,现在怎么办?您可以在两个副本上发送,只有一个(哪一个?),其他对象?所以它被删除了,如果您想传递它,请使用移动构造函数/分配和
std::move


编辑:由于空构造函数也被删除,您不能使用
mSockets[key]=…
。因此我们必须依赖
insert
/
emplace
。为什么?
操作符[]
on-map要求存在值类型的默认构造函数。我不知道为什么,但它在这里。

您不能将
map
boost::asio::ip::tcp::socket
一起用作值,因为
map
要求其值是默认可构造的(例如,在调用
map::operator[]
时创建默认构造实例),
asio::ip::tcp::socket
无法实现它,因为它的构造函数要求至少将
io\u context
对象作为参数


使用
shared_ptr
unique_ptr
作为map的值。

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

:

[…]
value\u type
必须来自
std::pieclewise\u构造,std::forward\u as\u tuple(key),std::tuple()
。使用默认分配器时,这意味着
键类型必须为
和
映射的\u类型必须是

但是,您可以使用
emplace()
并将套接字移动到正在构建emplace的
std::pair
中:

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


这将使用构造函数
tcp::socket(tcp::socket&&)
而不是
tcp::socket()
(您注意到它并不存在)。

这解决了一半的问题,最新的错误是“第二个(std::forward(std::get)(std::tuple2)调用“boost::asio::basic_stream_socket::basic_stream_socket()”时没有匹配的函数)…)。谢谢你的建议,也许我们只缺少了一个组件。@KyleJ如果你的问题得到了回答,请接受答案。@TEDLYNMO没有。请稍等。已修复。这里的问题是
运算符[]
默认情况下,它使用默认构造函数插入一个值。由于
boost::asio::ip::tcp::socket
没有该值,因此存在问题。不要向已回答的问题添加更多问题。创建一个新问题。这很奇怪。我无法想象代码中单个对象直接管理多个套接字。在我的代码中,单个套接字就是wrapp由某个处理套接字逻辑的类初始化,并且只有该对象由其他对象聚合。这是有意义的。我看到有人使用了带有shared_ptr的向量。感谢您的再次确认!不是
std::map
要求包含的值类型是默认可构造的。它是
运算符[](const Key&Key);
,因此
emplace
操作符[](键和键)
可以处理没有默认构造函数的类型。@TEDLYNMO
操作符[]
对于移动语义不起作用-。但通常你是对的,只有
操作符[]
要求映射的值是默认可构造的,而不是
映射的所有成员。
可能我概括了太多的答案,但当我使用某个容器时,我希望它的所有成员都被启用,而不是执行一些像
emplace
插入新值这样的技巧。@rafix07你是对的,它与默认分配器和我还没有试着做我自己的。看起来很可怕:-)但是,
emplace
对我来说似乎很好。一个解决方法是首先检查密钥是否存在于映射中,如果不存在,则推送你想要的密钥。没有默认构造函数。它对我有效,至少在我遇到的类似问题中是这样的。