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.