Does the default constructor of std::pair<> set basic types (int, etc) to zero?
After writing:
std::pair<int, int> x;
Am I guaranteed that x.first and x.second are both zero? Or could they have any value?
The reason why I care is because I'm trying to determine whether a map whose values are pointers is guaranteed to return NULL if I access an element that's not in the map. I.e., if I do:
std::map<int, void*> my_map;
std::cout << int(my_map[5]) << std::endl;
then am I guaranteed to get zero (NULL)? Or is the behavior undefined?
Yes, that guarantee holds true. Quoting the C++11 standard, §20.3.2/2-3:
constexpr pair();
2 Requires:
is_default_constructible<first_type>::value
istrue
andis_default_constructible<second_type>::value
istrue
.
3 Effects: Value-initializesfirst
andsecond
.
And §8.5/7:
To value-initialize an object of type
T
means:
- if
T
is a (possibly cv-qualified) class type with a user-provided constructor, then the default constructor forT
is called (and the initialization is ill-formed ifT
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, ifT
'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.
And lastly, §8.5/5:
To zero-initialize an object or reference of type
T
means:
- if
T
is a scalar type, the object is set to the value0
(zero), taken as an integral constant expression, converted toT
;- if
T
is a (possibly cv-qualified) non-union class type, each non-static data member and each base-class subobject is zero-initialized and padding is initialized to zero bits;- if
T
is a (possibly cv-qualified) union type, the object’s first non-static named data member is zero-initialized and padding is initialized to zero bits;- if
T
is an array type, each element is zero-initialized;- if
T
is a reference type, no initialization is performed.
From C++11 standard, section § 20.3.2
constexpr pair();
...
Effects: Value-initializes first and second.
So it is well-defined that the default initialization of an std::pair<int, int>
object will result in both members being set to 0.
Yes, they are zero-initialized. A citation of Bjarne Stroustrup's "The C++ Programming Language" (3rd edn, Ch. 17.4.1.7):
The result of
m[k]
is equivalent to the result of(*(m.insert(make_pair(k,V())).first)).second
, whereV()
is the default value of the mapped type. When you understand that equivalence, you probably understand associative containers.
For standard citations what default-initialized means look at the others answers.