1

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 thirdparty 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?

Please help.

kakyo
  • 8,886
  • 12
  • 62
  • 119

1 Answers1

2

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.

Indiana Kernick
  • 4,733
  • 2
  • 22
  • 47
  • 1
    Thanks so much! I'm pretty new to C++11 indeed. – kakyo Oct 31 '19 at 05:12
  • Btw, the current compiler error messages are as cryptic as pre-C++11 days, is there a knowledge base for working through these errors? – kakyo Oct 31 '19 at 05:14
  • @kakyo I guess there's old stackoverflow questions. If you want better error messages, use a fresh new C++17 compiler. – Indiana Kernick Oct 31 '19 at 05:17
  • @kakyo Though even that doesn't really help that much. Understanding the cryptic error messages comes with experience. C++ is a complicated language so the error messages are always going to complicated. – Indiana Kernick Oct 31 '19 at 05:22