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

halfer
  • 19,824
  • 17
  • 99
  • 186
kakyo
  • 10,460
  • 14
  • 76
  • 140

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
  • 5,041
  • 2
  • 20
  • 50
  • 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