为什么这个特定的std :: map初始化有效?

时间:2012-12-29 07:54:05

标签: c++ map

我正在尝试了解如何初始化std :: map。我在网上看到了以下初始化地图的方法(注意Test& t = mylist[0]部分):

#include <iostream>
#include <map>

using namespace std;

class Test
{
  public:
   Test():i_(0) { cout<<"Calling constructor"<<endl;}
   ~Test() { cout <<"Calling destructor"<<endl;}
  private:
   int i_;
};

int main(int argc, char **argv)
{
  map<unsigned,Test> mylist;
  cout << "Before "<<mylist.size()<<endl;
  Test& t = mylist[0];
  cout << "After "<<mylist.size()<<endl;
  return 0;
}

天真地,我原本期望以下工作,

Test t;
mylist[0] = t;

但是我觉得为什么第一种方法正常运作会伤害我的大脑!对象如何初始化?这是暂时的,因为从技术上来说,单独使用表达式mylist[0];会创建一个对象(但是如何?)

提前致谢!

2 个答案:

答案 0 :(得分:4)

根据cppreference.com

  

[std::map::operator[]]使用key作为键和默认构造的映射值,将新元素插入容器,并返回对新构造的映射值的引用。如果已存在具有键key的元素,则不会执行任何插入,并返回对其映射值的引用。

这意味着当执行Test& t = mylist[0];时,会调用Test()(您将看到“调用构造函数”)并且此对象已插入mapmylist “密钥为0。由于在调用this时地图中没有带有该键的元素,因此此操作会将mylist的大小增加一个。

答案 1 :(得分:1)

是的,std :: map上的[]运算符将使用值类的默认构造函数创建一个新对象。

http://www.cplusplus.com/reference/map/map/operator[] /:

  

如果x与容器中任何元素的键不匹配,则为   function使用该键插入一个新元素并返回一个引用   到它的映射值。请注意,这总是会增加地图大小   一,即使没有为元素(元素)分配映射值   是使用其默认构造函数构造的。

如果该类没有默认构造函数,则会出现编译错误。