写完后:
std::pair<int, int> x;
我保证x.first和x.second都是零吗?或者他们可以有任何价值吗?
我关心的原因是因为我正在尝试确定如果我访问一个不在地图中的元素,那么值为指针的地图是否保证返回NULL。即,如果我这样做:
std::map<int, void*> my_map;
std::cout << int(my_map[5]) << std::endl;
然后我保证得到零(NULL)?或者行为未定义?
答案 0 :(得分:34)
是的,这种保证是正确的。引用C ++ 11标准,§20.3.2/ 2-3:
constexpr pair();
2 要求:
is_default_constructible<first_type>::value
为true
而is_default_constructible<second_type>::value
为true
。
3 效果:值初始化first
和second
。
并且§8.5/ 7:
value-initialize
T
类型的对象意味着:
- 如果
T
是具有用户提供的构造函数的(可能是cv限定的)类类型,则调用T
的默认构造函数(如果{{1,则初始化为格式错误没有可访问的默认构造函数);- 如果
T
是一个(可能是cv限定的)非联合类类型而没有用户提供的构造函数,那么该对象是零初始化的,如果T
隐式声明的默认值构造函数是非平凡的,该构造函数被调用。- 如果
T
是数组类型,则每个元素都是值初始化的;- 否则,该对象为零初始化。
最后,§8.5/ 5:
零初始化
T
类型的对象或引用意味着:
- 如果
T
是标量类型,则将对象设置为值T
(零),作为整数常量表达式,转换为0
;- 如果
T
是(可能是cv限定的)非联合类类型,则每个非静态数据成员和每个基类子对象都是零初始化的,并且填充初始化为零位;- 如果
T
是一个(可能是cv限定的)联合类型,则该对象的第一个非静态命名数据成员被零初始化,并且填充被初始化为零位;- 如果
T
是数组类型,则每个元素都是零初始化的;- 如果
T
是引用类型,则不执行初始化。
答案 1 :(得分:5)
从C ++ 11标准,§20.3.2
部分constexpr pair();
...
Effects: Value-initializes first and second.
因此明确定义std::pair<int, int>
对象的默认初始化将导致两个成员都设置为0.
答案 2 :(得分:4)
是的,它们是零初始化的。引用Bjarne Stroustrup的“The C ++ Programming Language”(3rd edn,Ch.17.4.1.7):
m[k]
的结果等同于(*(m.insert(make_pair(k,V())).first)).second
的结果,其中V()
是映射类型的默认值。当你理解了等价时,你可能理解了关联容器。
对于标准引文,默认初始化意味着查看其他答案。
答案 3 :(得分:2)
是的,pair将调用默认构造函数。