内置类型的 std::map 默认值
Posted
技术标签:
【中文标题】内置类型的 std::map 默认值【英文标题】:std::map default value for build-in type 【发布时间】:2011-05-30 06:23:19 【问题描述】:最近,我对 std::map operator[] 函数感到困惑。 在 MSDN 库中,它说:“如果未找到参数键值,则将其与数据类型的默认值一起插入。” 我试图为这个问题寻找更准确的解释。例如这里: std::map default value 在这个页面中,Michael Anderson 说“默认值是由默认构造函数(零参数构造函数)构造的”。
现在我的任务是:“内置类型的默认值是多少?”。它与编译器有关吗?或者 c++ 标准委员会是否有针对这个问题的标准?
我在 Visual Studio 2008 上对“int”类型进行了测试,发现“int”类型的值是 0。
【问题讨论】:
我用“bool”类型做了一个测试。还有一些奇怪的东西:当我使用“bool b = new bool()”时,b 的值变成了 0;但是当我使用“bool *pb = new bool[10]; pb[0] = new bool();”然后 pb[0] 变成 1,即正值。哦,我在visual studio 2008上做了这个测试。 当你写pb[0] = new bool();
时,new bool()
是一个指针,而p[0]
是一个布尔值。指针可以隐式转换为bool
,如果指针为空指针,则返回结果false
,否则返回true
。因此,您观察到的真实值只是告诉您 new
没有返回空指针(当然,普通的 new
无论如何都不会返回)。另外,你泄露了分配。
【参考方案1】:
类类型对象的默认值是由类的默认构造函数设置的。对于内置类型,默认值为 0。
但请注意,未初始化的内置变量与已初始化为其默认值的变量之间存在差异。未初始化的内置函数可能会保存当时该变量的内存地址中的任何值。
int i; // i has an arbitrary undefined value
int x = int(); // x is 0
【讨论】:
以上链接已过时。见这里:stroustrup.com/glossary.html。不知道它有什么帮助 不。对于内置类型,未定义默认值。内置类型的默认构造函数什么都不做。【参考方案2】: |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。
【讨论】:
new T()
表示值初始化。值初始化不同于默认初始化。
new T() 暗示值初始化?使用new T()时值初始化和默认初始化有什么区别?【参考方案3】:
这是在标准中定义的,是的。在这种情况下,map 正在执行“默认初始化”。正如您所说,对于类类型,它调用无参数构造函数。
对于内置类型,在 '98 标准中,请参阅第 8.5 节“初始化程序”:
默认初始化 T 类型的对象意味着:
如果 T 是非 POD ... 如果 T 是数组类型 ... 否则,对象的存储是零初始化的
之前,
对 T 类型的对象进行零初始化存储意味着:
如果 T 是标量类型,则存储设置为转换为 T 的值 0(零)
标量类型有:
算术类型(整数、浮点) 枚举类型 指针类型 指向成员类型的指针特别是,您看到的整数(初始化为零)的行为是由标准定义的,您可以依赖它。
【讨论】:
我刚刚在 C++11 标准中检查了这一点,它说的有些不同。它表示如果类型不是类或数组,则不执行初始化。所以我现在不确定标准容器中的默认值。 过时标准的引用具有误导性,因为默认情况下,许多 POD 实例没有默认初始化。即使在 C++98 中,POD 类型的默认设置也是根本不初始化它们。用 C++11 清理了术语(并且变得非常复杂)。只有值初始化才能可靠地进行零初始化。【参考方案4】: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是数组类型,那么每个元素都是值初始化的; 否则,对象被零初始化。
【讨论】:
以上是关于内置类型的 std::map 默认值的主要内容,如果未能解决你的问题,请参考以下文章