地图运算符[]的编译错误

时间:2014-03-21 14:20:36

标签: c++ map

为什么我得到" recMap [key] = rec;"的编译错误在下面的代码但等效的声明工作正常?我有其他代码可以做到这一点。我错过了什么简单的事情?

#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
}

2 个答案:

答案 0 :(得分:4)

请考虑以下代码段:

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

即使没有为键0插入对象,这实际上也能正常工作。原因是,std::map::at()std::map::operator []()之间存在差异:

std::map::at()仅返回对地图内对象的引用。如果给定键没有对象,则抛出异常。

std::map::operator []()也会返回引用,但是如果给定键没有对象,则在地图内创建对象并返回对此新创建对象的引用。要创建对象std::map,必须调用默认构造函数(没有其他参数的构造函数)。

这就是你编码不会编译的原因:你的类MyRec不是默认构造的,但是std::map::operator []需要这个。


因此,您有三个选择:

  1. 使用std::map::insert()
  2. 使用std::map::emplace()
  3. 使MyRec默认可构造。

答案 1 :(得分:0)

在您的代码中,您提到您期望[] operator的工作方式与:

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

与该声明相同;而它与:

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

这样写的,希望更容易理解为什么代码没有编译(也就是说,MyRec没有定义parameter-less constructor)。