Depending on which overload we're talking about, std::unordered_map::operator[]
is equivalent to [unord.map.elem]
T& operator[](const key_type& k)
{
return try_emplace(k).first->second;
}
(the overload taking an rvalue-reference just moves k
into try_emplace
and is otherwise identical)
If an element exists under key k
in the map, then try_emplace
returns an iterator to that element and false
. Otherwise, try_emplace
inserts a new element under the key k
, and returns an iterator to that and true
[unord.map.modifiers]:
template <class... Args>
pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
Interesting for us is the case of there being no element yet [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)...)
(the overload taking an rvalue-reference just moves k
into forward_as_tuple
and, again, is otherwise identical)
Since value_type
is a pair<const Key, T>
[unord.map.overview]/2, this tells us that the new map element will be constructed as:
pair<const Key, T>(piecewise_construct, forward_as_tuple(k), forward_as_tuple(std::forward<Args>(args)...));
Since args
is empty when coming from operator[]
, this boils down to our new value being constructed as a member of the pair
from no arguments [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.
So yes, your code is guaranteed to return 0…
std::optional
? – Erdmanstd::optional
object that holds no contained value is still an initialized object. – Soundingstd::optional
has_value
would test it but it fails, so I guess you are correct. – Forgetfulstd::optional
was placed was in a already used memory page, and that memory location was also previously set to something else than zero? Or did you inspect the produced assembly and noticed it explicitly writes zeroes there? – Legislativestd::optional
and I think the compiler optimised it to zero. I did not go into the debugger, but could give it a try. – Forgetful