Abhängig von der Überlastung, von der wir sprechen, std::unordered_map::operator[]
entspricht dies [unord.map.elem]
T& operator[](const key_type& k)
{
return try_emplace(k).first->second;
}
(Die Überlastung, die eine r-Wert-Referenz nimmt, bewegt sich nur k
hinein try_emplace
und ist ansonsten identisch.)
Wenn ein Element unter Schlüssel k
in der Karte vorhanden ist, wird try_emplace
ein Iterator für dieses Element und zurückgegeben false
. Andernfalls wird try_emplace
ein neues Element unter den Schlüssel eingefügtk
und ein Iterator an diesen und true
[unord.map.modifiers] zurückgegeben :
template <class... Args>
pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
Interessant für uns ist der Fall, dass es noch kein Element gibt [unord.map.modifiers] / 6 :
Andernfalls wird ein Objekt vom Typ value_type
eingefügt, mit dem erstellt wurdepiecewise_construct, forward_as_tuple(k), forward_as_tuple(std::forward<Args>(args)...)
(Die Überlastung, die eine r-Wert-Referenz nimmt, bewegt sich nur k
hinein forward_as_tuple
und ist ansonsten wieder identisch.)
Da value_type
es sich um eine pair<const Key, T>
[unord.map.overview] / 2 handelt , wird das neue Kartenelement wie folgt erstellt:
pair<const Key, T>(piecewise_construct, forward_as_tuple(k), forward_as_tuple(std::forward<Args>(args)...));
Da args
es leer ist, wenn es von kommt operator[]
, läuft dies darauf hinaus, dass unser neuer Wert als Mitglied von pair
from no arguments [pairs.pair] / 14 konstruiert wird, was eine direkte Initialisierung [class.base.init] / 7 eines Wertes vom Typ T
using ist ()
als Initialisierer, der auf die Wertinitialisierung hinausläuft [dcl.init] /17.4 . Die Wertinitialisierung von a int
ist die Nullinitialisierung [dcl.init] / 8 . Und die Nullinitialisierung von a initialisiert dies int
natürlich int
auf 0 [dcl.init] / 6 .
Also ja, Ihr Code gibt garantiert 0 zurück…