简体   繁体   中英

Compile error for map operator []

Why do I get a compile error for "recMap[key] = rec;" in the below code but the equivalent statements work fine? I have other code that does this. What simple thing am I missing?

#include <map>

class MyRec {
   public:
   MyRec(int numberIn) : myNumber(numberIn) { };
   int myNumber;
};

int main(int argc, char **argv)
{
   typedef std::map<int, MyRec> Recs;
   Recs recMap;
   int num=104702;
   int key=100923;

   MyRec rec(num);

   recMap[key] = rec; // Doesn't compile
   // error: no matching function for call to MyRec::MyRec()
   // samp.cpp:5: note: candidates are: MyRec::MyRec(int)
   // samp.cpp:3: note:                 MyRec::MyRec(const MyRec&)

   // Why do I receive the compile error for the above if it is the same as:
   (*((recMap.insert(std::make_pair(key,rec))).first)).second;

   recMap.insert(std::pair<int, MyRec>(key,rec)); // Works also of course
}

Consider this snippet:

std::map<int, Foo> map;
map[0];

This will actually work fine even if havent inserted an object for key 0. The reason is, that there is a difference between std::map::at() and std::map::operator []() :

std::map::at() only returns a reference to an object inside the map. If there isnt an object for the given key, an exception is thrown.

std::map::operator []() does also return a reference, however if there no object for the given key, it creates an object inside the map and returns a reference to this newly created object. In order to create the object std::map must call the default constructor (a constructor with no additional arguments).

That is the reason why you code wont compile: Your class MyRec is not default constructable, but std::map::operator [] requires this.


Thus you have three options:

  1. Use std::map::insert()
  2. Use std::map::emplace()
  3. Make MyRec default constructable.

In your code, you mention that you expect the [] operator to work the same as:

    (*((recMap.insert(std::make_pair(key,rec))).first)).second;

But it is not the same as that statement; rather it's the same as:

    (*((recMap.insert(std::make_pair(key,MyRec()))).first)).second;

Written like this, hopefully it's easier to see why the code doesn't compile (that is, MyRec does not define a parameter-less constructor ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM