std::unordered_map operator[] 是否对不存在的密钥进行零初始化?

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

根据cppreference.com,std::map::operator[]对不存在的值进行零初始化。

但是,同一站点没有提到 std::unordered_map::operator[] 的零初始化,只是它确实有一个依赖于此的示例。

当然这只是一个参考站点,不是标准站点。那么,下面的代码可以吗?

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

在您链接的网站上写着:

When the default allocator is used, this results in the key being copy constructed from key and the mapped value being value-initialized.

所以 intvalue-initialized:

The effects of value initialization are:

[...]

4) otherwise, the object is zero-initialized

这就是为什么结果是 0

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

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

(采用右值引用的重载只是将 k 移动到 try_emplace 中,否则是相同的)

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

template <class... Args>
pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);

我们感兴趣的是还没有元素的情况[unord.map.modifiers]/6:

Otherwise inserts an object of type value_­type constructed with 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,这告诉我们新的地图元素将构造为:

pair<const Key, T>(piecewise_­construct, forward_­as_­tuple(k), forward_­as_­tuple(std​::​forward<Args>(args)...));

由于 args 来自 operator[] 时为空,这归结为我们的新值被构造为 pair 的成员,没有参数 [pairs.pair]/14 which is direct initialization [class.base.init]/7 of a value of type T using () as initializer which boils down to value initialization [dcl.init]/17.4. Value initialization of an int is zero initialization [dcl.init]/8. And zero initialization of an int naturally initializes that int to 0 [dcl.init]/6

所以是的,你的代码保证 return 0…