0
#include <iostream>
#include <string>

int main() {
    std::pair<std::string, int> s;
    std::cout << s.second << std::endl;
}

在这个例子s.second0虽然它没有被初始化。您能否提供指向 C++ 标准的链接,其中定义了为什么0。我知道这是因为s.second被初始化int(),但无法找到标准中声明的int()0

4

3 回答 3

6

它是

8.5 初始化器 [dcl.init]

10) 初始化器为空括号集的对象,即 (),应进行值初始化。

7) 对 T 类型的对象进行值初始化意味着:
— 如果 T 是具有用户提供的构造函数 (12.1) 的(可能是 cv 限定的)类类型(第 9 条),则调用 T 的默认构造函数(并且如果 T 没有可访问的默认构造函数,则初始化格式错误);
— 如果 T 是没有用户提供的构造函数的(可能是 cv 限定的)非联合类类型,则该对象是零初始化的,如果 T 的隐式声明的默认构造函数是非平凡的,则调用该构造函数。
— 如果 T 是一个数组类型,那么每个元素都是值初始化的;
— 否则,对象被零初始化。

我猜

5) 对 T 类型的对象或引用进行零初始化意味着:
— 如果 T 是标量类型 (3.9),则将对象设置为值 0(零),作为整数常量表达式,转换为 T;[...]

于 2013-03-21T13:24:45.833 回答
5

我知道这是因为 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;

— [...]

于 2013-03-21T13:25:34.830 回答
3

我知道这是因为 s.second 由 int() 初始化

该标准实际上并没有说second是用int(). 它只是给出了std::pair使用默认构造函数创建 a 的效果(第 20.3.2 节):

效果:值初始化第一个和第二个。

值初始化定义为(§8.5):

对类型对象进行值初始化T意味着:

  • ifT是(可能是 cv 限定的)类类型(第 9 条)[...]

  • ifT是(可能是 cv 限定的)非联合类类型 [...]

  • 如果T是数组类型,[...]

  • 否则,对象被零初始化。

Whcih 导致second被零初始化,因为它是int(§8.5):

对类型的对象或引用进行零初始化T意味着:

  • 如果T是标量类型(3.9),则将对象设置为值0(零),取整型常量表达式,转换为T;

  • [...]

于 2013-03-21T13:30:07.277 回答