STL映射是否在插入时初始化基元类型?

时间:2009-02-03 17:00:03

标签: c++ dictionary stl initialization primitive-types

我有std::map这样:

map<wstring,int> Scores;

它存储球员的名字和分数。当有人获得分数时,我会这样做:

Scores[wstrPlayerName]++;

当地图中没有带有键wstrPlayerName的元素时,它会创建一个元素,但是在增量之前它是初始化为零还是为空还是未定义?

我应该每次在增量之前测试元素是否存在吗?

我只是想知道,因为我认为原始类型的东西在创建时总是未定义的。

如果我写的话:

int i;
i++;

编译器警告我,我未定义,当我运行程序时,它通常不为零。

4 个答案:

答案 0 :(得分:62)

operator []如下所示:

Value& map<Key, Value>::operator[](const Key& key);

如果您使用尚未在地图中的来调用它,则会默认构建的新实例,将其放在下的地图中你传入了> key ,并返回对它的引用。在这种情况下,你有:

map<wstring,int> Scores;
Scores[wstrPlayerName]++;

此处的值为 int ,并且ints默认构造为0,就像使用 int()初始化它们一样。其他原始类型的初始化类似(例如 double() long() bool()等)。

最后,您的代码在地图中放置一对新对(wstrPlayerName,0),然后返回对int的引用,然后将其递增。因此,如果您希望事物从0开始,则无需测试元素是否存在。

答案 1 :(得分:11)

这将默认构造value的新实例。对于整数,默认构造为0,因此按预期工作。

答案 2 :(得分:5)

在递增之前,您不应该测试该项是否存在。正如其他人所说的那样,[]运算符完全按照你的需要去做。

但是如果默认构造的值对你不起作用怎么办?在您的情况下,查找元素是否已存在的最佳方法是尝试插入它。 insert的{​​{1}}成员函数返回std::map。无论插入成功还是失败,该对的第一个元素都将指向所需的对象(您的新对象或已存在的对象)。然后,您可以根据需要更改其值。

答案 3 :(得分:1)

检查初始化规则。

请参见4.9.5 C ++ Prog Lang或C ++ std书的初始化。根据您的变量是否为本地,静态,用户定义或const默认初始化可能会发生。

在您的情况下,int称为POD(Plain old Datatype)。任何自动(在堆/局部变量上创建)POD变量都不是默认初始化的。因此,对于你,上面的“i”将没有零值。

在堆中定义时,始终养成初始化POD的习惯。您甚至可以使用int()来初始化值。