-1

我试图了解如何初始化 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];单独编写表达式会创建一个对象(但是如何?)

提前致谢!

4

2 回答 2

4

根据cppreference.com

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

这意味着当Test& t = mylist[0];被执行时,Test()被调用(你会看到“调用构造函数”)并且这个对象被插入到带有键的map“ ”中。由于在调用此键时映射中没有具有该键的元素,因此此操作将大小恰好增加一。mylist0mylist

于 2012-12-29T08:01:22.327 回答
1

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

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

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

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

于 2012-12-29T07:59:37.413 回答