【问题标题】:Are elements added to a std::map automatically initialised?添加到 std::map 的元素是否会自动初始化?
【发布时间】:2015-08-27 10:52:45
【问题描述】:

假设我有一张地图

std::map<int, double> foo;

我写作foo[2] += 3.0; 的行为是否已定义?也就是说,在我的情况下,是否会自动初始化任何隐式添加的地图元素(希望是 0.0)?

如果不是,我是否会引入一大堆未定义的行为?如果是这样,我可以用分配器做一些时髦的事情来强制初始化为0.0吗?

【问题讨论】:

标签: c++ dictionary initialization


【解决方案1】:

是的,它将是value-initialized(在您的情况下为0.0)。根据cppreference:

返回对映射到等效键的值的引用 键,如果该键不存在则执行插入。

如果执行插入,映射的值是值初始化的 (为类类型默认构造,否则为零初始化)和 返回对它的引用。

【讨论】:

  • “否则零初始化”。这就是它的症结所在。谢谢。
  • 这一直是真的,还是只是在 c++11 中? C++11 在填充默认值方面比以前做得更多,但我不知道这是否是其中一种情况
  • @AaronMcDaid 在 C++03 中也是如此。
  • @AaronMcDaid C++11 为值初始化添加了更多语法,但值初始化的结果没有改变。
  • @songyuanyao,根据this,有些东西从C++03变成了new T()的意思的C++11。 “具有动态存储持续时间的标量和 POD 类型被认为未初始化(从 C++11 开始,这种情况被重新归类为默认初始化的一种形式)。” 这就是为什么我很好奇 C关于这个问题,++03 确实与 C++11 相同,也许为map 元素引入了类似的更改(类似于该引用)。但我想如果有区别,你链接的页面会这样说。
【解决方案2】:

N3337 [map.access]/1 效果:如果映射中没有与x等效的键,则将value_type(x,T())插入映射中。

T() 是值初始化,这是内置类型的情况导致零初始化。因此,foo[2] 将在您的地图中插入一个零初始化的double,因此您的代码是明确定义的。

【讨论】:

    【解决方案3】:

    是的,当在不存在的键上使用operator[] 时,它们会自动初始化值。特别是在第 23.4.4.3/1 节中描述的标准中(当谈到 operator[] 时):

    效果:如果映射中没有与 x 等效的键,则将 value_type(x, T()) 插入映射中。

    对于大多数数字类型,包括 double,表达式 T() 会生成该类型的值初始化元素,因此在您的情况下会生成 0.0。

    【讨论】:

    • 但是double 并没有真正的默认构造函数。
    • 它们实际上是值初始化的,否则 OP 的代码会调用 UB。
    • @juanchopanza 实际上是the same thing for double。
    • 我在考虑默认初始化,因为您最初说它是默认构造的。默认初始化与值初始化不同。
    • 而且double没有默认构造函数。
    猜你喜欢
    • 2015-02-11
    • 1970-01-01
    • 2012-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-01
    • 1970-01-01
    • 2016-07-30
    相关资源
    最近更新 更多