12

Suppose I have a map

std::map<int, double> foo;

Is the behaviour on my writing foo[2] += 3.0; defined? That is, are any implicitly added map elements automatically initialised (hopefully to 0.0) in my case?

If not, am I introducing a truck-load of undefined behaviour? If so, could I do something funky with an allocator to enforce initialisation to 0.0?

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
P45 Imminent
  • 8,319
  • 4
  • 35
  • 78

3 Answers3

7

Yes, it will be value-initialized (as 0.0 in your case). According to cppreference:

Returns a reference to the value that is mapped to a key equivalent to key, performing an insertion if such key does not already exist.

If an insertion is performed, the mapped value is value-initialized (default-constructed for class types, zero-initialized otherwise) and a reference to it is returned.

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • 3
    "zero-initialized otherwise". That's the crux of it. Thank you. – P45 Imminent Aug 27 '15 at 10:57
  • 1
    Has this always been true, or just in c++11? C++11 does much more to fill in defaults than previously, but I don't know if this is one of those contexts – Aaron McDaid Aug 27 '15 at 11:22
  • 2
    @AaronMcDaid This is also true in C++03. – TartanLlama Aug 27 '15 at 11:32
  • @AaronMcDaid C++11 added more syntax for value initialization but the result of value initialization didn't change. – songyuanyao Aug 27 '15 at 11:33
  • @songyuanyao, according to [this](http://en.cppreference.com/w/cpp/language/default_initialization) something has changed from C++03 to C++11 in the meaning of `new T()`. *"Scalars and POD types with dynamic storage duration were considered to be not initialized (since C++11, this situation was reclassified as a form of default initialization). "* That's why I'm curious if C++03 really is the same as C++11 as regards this question, perhaps a similar change (similar to that quote) has been introduced for `map` elements. But I suppose if there was a difference, the page you linked would say so. – Aaron McDaid Aug 27 '15 at 12:46
  • (... in other words, I didn't say that the result of value initialization has changed. Just that, in some contexts (perhaps not relevant to this question), there has been a change in which initializations are used.) – Aaron McDaid Aug 27 '15 at 12:48
0

N3337 [map.access]/1 Effects: If there is no key equivalent to x in the map, inserts value_type(x,T()) into the map.

T() is value-initialization, which is the case of built-in types causes zero-initialization. As such, foo[2] will insert a zero-initialized double into your map, so your code is well-defined.

TartanLlama
  • 63,752
  • 13
  • 157
  • 193
-1

Yes, they are automatically value initialized when using operator[] on a non existing key. Specifically in the standard it's described at §23.4.4.3/1 (when talking about operator[]):

Effects: If there is no key equivalent to x in the map, inserts value_type(x, T()) into the map.

For most numeric types, including double, the expression T() yields a value-initialized element of that type, therefore yielding 0.0 in your case.

Shoe
  • 74,840
  • 36
  • 166
  • 272
  • But a `double` doesn't really have a default constructor. – P45 Imminent Aug 27 '15 at 10:57
  • They are actually value initialized, otherwise OP's code would invoke UB. – juanchopanza Aug 27 '15 at 10:58
  • @juanchopanza It's actually [the same thing](http://stackoverflow.com/a/1613383/493122) for `double`. – Shoe Aug 27 '15 at 11:01
  • I was thinking of default initialization, since you'd originally said it is default constructed. Default initialization isn't the same thing as value initialization. – juanchopanza Aug 27 '15 at 14:15
  • And double does not have a default constructor. – juanchopanza Aug 29 '15 at 09:19
  • @juanchopanza That's why I said it's the same thing for `double`. The "for `double`" part is the key. Also [`double` is default constructible](http://coliru.stacked-crooked.com/a/c537d2c9e6373bcd). I guess you can argue that `double` does not have a constructor but it's default constructible, but that's hardly relevant here. If you want to be pedantic, so be it. – Shoe Aug 29 '15 at 11:06