我有std::map
这样:
map<wstring,int> Scores;
它存储球员的名字和分数。当有人获得分数时,我会这样做:
Scores[wstrPlayerName]++;
当地图中没有带有键wstrPlayerName
的元素时,它会创建一个元素,但是在增量之前它是初始化为零还是为空还是未定义?
我应该每次在增量之前测试元素是否存在吗?
我只是想知道,因为我认为原始类型的东西在创建时总是未定义的。
如果我写的话:
int i;
i++;
编译器警告我,我未定义,当我运行程序时,它通常不为零。
答案 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()来初始化值。