Does std::unordered_map operator[] do zero-initialization for non-exisiting key?

hyd*_*yde 25 c++ unordered-map zero-initialization

According to cppreference.com, std::map::operator[] for non-existing value does zero-initialization.

However, the same site does not mention zero-initialization for std::unordered_map::operator[], except it does have an example which relies on this.

Of course this is just a reference site, not the standard. So, is the code below ok or not?

#include <unordered_map>
int main() {
    std::unordered_map<int, int> map;
    return map[42];     // is this guaranteed to return 0?
}
Run Code Online (Sandbox Code Playgroud)

Bla*_*aze 22

在您链接的网站上,它说:

当使用默认分配器时,这会导致键从键复制构造,映射值被值初始化。

所以int值初始化的

值初始化的效果是:

[...]

4) 否则,对象被零初始化

这就是为什么结果是0


Mic*_*zel 15

根据我们谈论的重载,std::unordered_map::operator[]相当于[unord.map.elem]

T& operator[](const key_type& k)
{
    return try_­emplace(k).first->second;
}
Run Code Online (Sandbox Code Playgroud)

(采用右值引用的重载只是k进入try_emplace并且在其他方​​面是相同的)

如果k映射中的key 下存在元素,则try_emplace返回该元素的迭代器和false。否则,try_emplace在 key 下插入一个新元素k,并返回一个迭代器和true [unord.map.modifiers]

T& operator[](const key_type& k)
{
    return try_­emplace(k).first->second;
}
Run Code Online (Sandbox Code Playgroud)

对我们来说有趣的是还没有元素[unord.map.modifiers]/6 的情况

否则插入一个类型为value_­type构造的对象piecewise_­construct, forward_­as_­tuple(k), forward_­as_­tuple(std?::?forward<Args>(args)...)

(采用右值引用的重载刚刚k进入,forward_­as_­tuple并且在其他方​​面是相同的)

由于value_typepair<const Key, T> [unord.map.overview]/2,这告诉我们新的地图元素将被构造为:

template <class... Args>
pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
Run Code Online (Sandbox Code Playgroud)

由于args来自 from 时为空operator[],这归结为我们的新值被构造为pairfrom no arguments [pairs.pair]/14的成员,这是使用类型值的直接初始化[class.base.init]/7作为初始化器,归结为值初始化[dcl.init]/17.4。an 的值初始化为零初始化[dcl.init]/8。并且 a 的零初始化自然会将其初始化为 0 [dcl.init]/6T()intintint

所以是的,你的代码肯定会返回 0…