2012-12-29 64 views
-1

我想了解如何初始化std :: map。我看到在网络上初始化地图的方式如下(注意Test& t = mylist[0]部分):为什么这个特殊的std :: map初始化工作?

#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];会创建一个对象(但是怎么样?)

在此先感谢!

+5

如果操作符[]不存在,则将其插入到映射中。因此,地图中有一个有效的对象用于参考。 – chris

+2

@chris听起来像是对我的回答。 – Corbin

+0

@chris谢谢你!我查了一下操作符[],如果不存在,它肯定会插入一个新元素。干杯! – covariantmonkey

回答

4

根据cppreference.com

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

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

+0

谢谢!就是这样! – covariantmonkey

1

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

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

如果x不匹配的容器中的任何元素的键,所述 函数插入一个新元素与该键并返回一个参考 其映射的值。请注意,即使未将映射值分配给元素(使用其默认构造函数构造元素 ),也总会将地图大小增加 个。

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

+0

谢谢。很高兴知道默认的构造函数。 – covariantmonkey

相关问题