std::map default value for build-in type

This is defined in the standard, yes. map is performing "default initialization" in this case. As you say, for class types, that calls a no-arguments constructor.

For built-in types, in the '98 standard, see section 8.5, "Initializers":

To default-initialize an object of type T means:

  • if T is a non-POD ...
  • if T is an array type ...
  • otherwise, the storage for the object is zero-initialized

And, previously,

To zero-initialize storage for an object of type T means:

  • if T is a scalar type, the storage is set to the value 0 (zero) converted to T

Scalar types are:

  • Arithmetic types (integer, floating point)
  • Enumeration types
  • Pointer types
  • Pointer to member types

In particular, the behaviour you see with an integer (initialized to zero) is defined by the standard, and you can rely on it.


The C++11 standard still requires that std::map zero-initializes built in types (as did the previous standard), but the reasons are a bit different to those in Luke Halliwell's answer. In particular, to 'default-initialize' a built-in data type doesn't mean zero-initialize in the C++11 standard, but rather it would mean 'do nothing'. What actually happens in std::map::operator[] is a 'value-initialization'.

Nevertheless, the end result in the new standard is the same as in Luke's answer. The values will be zero-initialized. Here are the relevant parts of the standard:

Section 23.4.4.3 "map element access" says

T& operator[](const key_type& x);

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

...

The expression T() is described in section 8.5

An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.

X a();

And this kind of 'value-initialization' is described in the same section

To value-initialize an object of type T means:

  • if T is a (possibly cv-qualified) class type (Clause 9) with a user-provided constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
  • if T is a (possibly cv-qualified) non-union class type without a user-provided constructor, then the object is zero-initialized and, if T’s implicitly-declared default constructor is non-trivial, that constructor is called.
  • if T is an array type, then each element is value-initialized;
  • otherwise, the object is zero-initialized.

The default value of class-type objects is that set by the default constructor of the class. For built-in types the default value is 0.

But note that there is a difference between a built-in variable that isn't initialized, and one initialized to its default value. A built-in that is not initialized will probably hold whatever value was in that variable's memory address at the time.

int i;          // i has an arbitrary undefined value
int x = int();  // x is 0

 |expression:   | POD type T                               | non-POD type T
 ==================================================================================================
 | new T         | not initialized                          | default-initialized
 | new T()       | always default-initialized               | always default-initialized
 | new T(x)      | always initialized via a constructor     | always initialized via a constructor

As far as i know, stl uses new T() for default values, so it will be default-initialized, in case of int to 0.