#include <iostream>
#include <string>
int main() {
std::pair<std::string, int> s;
std::cout << s.second << std::endl;
}
在这个例子s.second
中0
虽然它没有被初始化。您能否提供指向 C++ 标准的链接,其中定义了为什么0
。我知道这是因为s.second
被初始化int()
,但无法找到标准中声明的int()
行0
。
它是
10) 初始化器为空括号集的对象,即 (),应进行值初始化。
和
7) 对 T 类型的对象进行值初始化意味着:
— 如果 T 是具有用户提供的构造函数 (12.1) 的(可能是 cv 限定的)类类型(第 9 条),则调用 T 的默认构造函数(并且如果 T 没有可访问的默认构造函数,则初始化格式错误);
— 如果 T 是没有用户提供的构造函数的(可能是 cv 限定的)非联合类类型,则该对象是零初始化的,如果 T 的隐式声明的默认构造函数是非平凡的,则调用该构造函数。
— 如果 T 是一个数组类型,那么每个元素都是值初始化的;
— 否则,对象被零初始化。
我猜
5) 对 T 类型的对象或引用进行零初始化意味着:
— 如果 T 是标量类型 (3.9),则将对象设置为值 0(零),作为整数常量表达式,转换为 T;[...]
我知道这是因为 s.second 由 int() 初始化,但在标准中找不到规定 int() 为 0 的行。
这是您在 C++11 标准中必须遵循的路径 - 此答案使用Draft n3485作为参考,它比当前的官方标准更新。
根据 C++11 标准的第 8.5/11 段:
初始化器是一组空括号的对象,即 (),应进行值初始化。[...]
此外,根据 C++11 标准的第 8.5/8 段:
对T 类型的对象进行值初始化意味着:
— 如果 T 是(可能是 cv 限定的)类类型(第 9 条),没有默认构造函数(12.1)或用户提供或删除的默认构造函数,则对象被默认初始化;
— 如果 T 是(可能是 cv 限定的)非联合类类型,没有用户提供或删除的默认构造函数,则该对象为零初始化,如果 T 具有非平凡的默认构造函数,则默认初始化;
— 如果 T 是一个数组类型,那么每个元素都是值初始化的;
—否则,对象是零初始化的。
最后(尽管这很直观),根据第 8.5/6 段:
对T 类型的对象或引用进行零初始化意味着:
—如果 T 是标量类型(3.9),则将对象设置为值 0(零),作为整数常量表达式,转换为 T;
— [...]
我知道这是因为 s.second 由 int() 初始化
该标准实际上并没有说second
是用int()
. 它只是给出了std::pair
使用默认构造函数创建 a 的效果(第 20.3.2 节):
效果:值初始化第一个和第二个。
值初始化定义为(§8.5):
对类型对象进行值初始化
T
意味着:
if
T
是(可能是 cv 限定的)类类型(第 9 条)[...]if
T
是(可能是 cv 限定的)非联合类类型 [...]如果
T
是数组类型,[...]否则,对象被零初始化。
Whcih 导致second
被零初始化,因为它是int
(§8.5):
对类型的对象或引用进行零初始化
T
意味着:
如果
T
是标量类型(3.9),则将对象设置为值0(零),取整型常量表达式,转换为T;[...]