話しているオーバーロードに応じてstd::unordered_map::operator[]、[unord.map.elem]と同等です。
T& operator[](const key_type& k)
{
return try_emplace(k).first->second;
}
(右辺値参照を取るオーバーロードは移動するだけです ktry_emplaceはする、それ以外は同じです)
要素がkマップのキーの下に存在する場合、try_emplaceその要素へのイテレータとを返しますfalse。それ以外の場合はtry_emplace、キーの下に新しい要素を挿入し、その要素kとtrue [unord.map.modifiers]にイテレータを返します。
template <class... Args>
pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
私たちにとって興味深いのは、まだ要素がない場合です[unord.map.modifiers] / 6:
それ以外の場合はvalue_type、piecewise_construct, forward_as_tuple(k), forward_as_tuple(std::forward<Args>(args)...)
(右辺値参照をとるオーバーロードは単に移動kするだけでforward_as_tuple、それ以外は同じです)
以来value_typeであるpair<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に要約されます。これは、使用するタイプの値の直接初期化[class.base.init] / 7です。値の初期化[dcl.init] /17.4に要約される初期化子として。の値の初期化はゼロ初期化[dcl.init] / 8です。そして、自然にゼロ初期化すると、自然に0 に初期化されます[dcl.init] / 6T()intintint。
つまり、コードは0を返すことが保証されています…