I'm trying to create an std::map for <MyKey, MyValue>
. MyKey
is an enum, MyValue
an external class.
Calling myMap.insert({ key, value })
always fails the compile with error
"cannot convert argument 1 from 'std::pair<MyKey, MyValue>' to 'std::pair<const _Kty,_Ty> &&'"
Although primitive data types always work with std::map.insert()
, this problem happens so often when trying to contain classes written by someone else. With different third-party classes, I've tried many workarounds such as constructing objects beforehand or setting their attributes after insertion. But I've yet to find a systematic way to fix this. It seems std::map
is much harder to get right than, say, python's dict
.
Example: with the thirdparty lib cppzmq
, Visual Studio 2017
enum MyKey {
key1,
key2
}
std::map<MyKey, zmq::socket_t> mymap;
std::shared_ptr<zmq::context_t> g_context = std::make_shared<zmq::context_t>(1);
zmq:socket_t sock(*g_context, zmq::socket_type::pair);
mymap.insert({ key1, sock });
gives me the above error.
What does this error mean and how to fix it in general?
If you want to insert a move-only object into a std::map
then your only option is to move it into map. Adapting your example, you could try this:
mymap.insert({key1, zmq:socket_t{*g_context, zmq::socket_type::pair}});
You could also do this:
zmq:socket_t sock{*g_context, zmq::socket_type::pair};
mymap.insert({key1, std::move(sock)});
// note that sock is in a "moved from" state after this point
I see that you're coming from Python and might not be familiar with move semantics so the answers to this question might be helpful.