33

最近,我对 std::map operator[] 函数感到困惑。在 MSDN 库中,它说:“如果未找到参数键值,则将其与数据类型的默认值一起插入。” 我试图为这个问题寻找更准确的解释。例如这里: std::map default value 在这个页面中,Michael Anderson 说“默认值是由默认构造函数(零参数构造函数)构造的”。

现在我的任务是:“内置类型的默认值是多少?”。它与编译器有关吗?或者 c++ 标准委员会是否有这个问题的标准?

我在 Visual Studio 2008 上对“int”类型进行了测试,发现“int”类型的值是 0。

4

4 回答 4

30

这是在标准中定义的,是的。在这种情况下,map 正在执行“默认初始化”。正如您所说,对于类类型,它调用无参数构造函数。

对于内置类型,在 '98 标准中,请参阅第 8.5 节“初始化程序”:

默认初始化 T 类型的对象意味着:

  • 如果 T 是非 POD ...
  • 如果 T 是数组类型...
  • 否则,对象的存储为零初始化

而且,以前,

对 T 类型的对象进行零初始化存储意味着:

  • 如果 T 是标量类型,则存储设置为值 0(零)转换为 T

标量类型是:

  • 算术类型(整数、浮点数)
  • 枚举类型
  • 指针类型
  • 指向成员类型的指针

特别是,您看到的整数(初始化为零)的行为是由标准定义的,您可以依赖它。

于 2010-12-24T03:47:00.650 回答
22

C++11 标准仍然要求 std::map 对内置类型进行零初始化(就像以前的标准一样),但原因与 Luke Halliwell 的回答中的原因有点不同。特别是,“默认初始化”内置数据类型并不意味着在 C++11 标准中进行零初始化,而是意味着“什么都不做”。实际发生的std::map::operator[]是“值初始化”。

尽管如此,新标准的最终结果与卢克的答案相同。这些值将被零初始化。以下是标准的相关部分:

第 23.4.4.3 节“地图元素访问”说

T& 运算符[](const key_type& x);

效果:如果地图中没有与 x 等效的键,则插入value_type(x, T())到地图中。

...

表达式T()在第 8.5 节中描述

初始化器是一组空括号的对象,即 (),应进行值初始化

X a();

这种“值初始化”在同一节中进行了描述

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

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

类类型对象的默认值是由类的默认构造函数设置的。对于内置类型,默认值为 0。

但请注意,未初始化的内置变量与已初始化为其默认值的变量之间存在差异。未初始化的内置函数可能会保存当时该变量的内存地址中的任何值。

int i;          // i has an arbitrary undefined value
int x = int();  // x is 0
于 2010-12-24T03:25:48.663 回答
5
 |expression:   | POD type T                               | non-POD type T
 ==================================================================================================
 | new T         | not initialized                          | default-initialized
 | new T()       | always default-initialized               | always default-initialized
 | new T(x)      | always initialized via a constructor     | always initialized via a constructor

据我所知,stl 使用 new T() 作为默认值,因此它将被默认初始化,以防 int 为 0。

于 2010-12-24T03:33:04.640 回答