是否为std :: pair<>的默认构造函数?将基本类型(int等)设置为零?

时间:2012-01-26 21:41:11

标签: c++

写完后:

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)?或者行为未定义?

4 个答案:

答案 0 :(得分:34)

是的,这种保证是正确的。引用C ++ 11标准,§20.3.2/ 2-3:

  

constexpr pair();

     

2 要求: is_default_constructible<first_type>::valuetrueis_default_constructible<second_type>::valuetrue
  3 效果:值初始化firstsecond

并且§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将调用默认构造函数。