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?
}
Depending on which overload we're talking about,
std::unordered_map::operator[]is equivalent to [unord.map.elem](the overload taking an rvalue-reference just moves
kintotry_emplaceand is otherwise identical)If an element exists under key
kin the map, thentry_emplacereturns an iterator to that element andfalse. Otherwise,try_emplaceinserts a new element under the keyk, and returns an iterator to that andtrue[unord.map.modifiers]:Interesting for us is the case of there being no element yet [unord.map.modifiers]/6:
(the overload taking an rvalue-reference just moves
kintoforward_as_tupleand, again, is otherwise identical)Since
value_typeis apair<const Key, T>[unord.map.overview]/2, this tells us that the new map element will be constructed as:Since
argsis empty when coming fromoperator[], this boils down to our new value being constructed as a member of thepairfrom no arguments [pairs.pair]/14 which is direct initialization [class.base.init]/7 of a value of typeTusing()as initializer which boils down to value initialization [dcl.init]/17.4. Value initialization of anintis zero initialization [dcl.init]/8. And zero initialization of anintnaturally initializes thatintto 0 [dcl.init]/6.So yes, your code is guaranteed to return 0…