【问题标题】:std::unordered_map initializationstd::unordered_map 初始化
【发布时间】:2012-01-20 14:53:35
【问题描述】:

当我第一次访问std::unordered_map using operator [] 中的元素时,它会自动创建。关于其初始化的保证(如果有的话)是什么? (保证是值初始化,还是只构造)?

例子:

std::unordered_map<void *, size_t> size;
char *test = new char[10];
size[test] += 10;

size[test] 在这个序列的末尾是否保证为 10?

【问题讨论】:

    标签: c++ std unordered-map


    【解决方案1】:

    size[test] 在这个序列的末尾是否保证为 10?

    是的。 在代码的最后一行,size[test] 将元素初始化为 T(),或者在本例中为 size_t()

    C++11 23.4.4.3 地图元素访问[map.access]

    T&amp; operator[](const key_type&amp; x);

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

    至于T(),具体的语言有点牵扯,所以我会尝试引用相关的部分:

    C++11 8.5.16 初始化器的语义如下。

    如果初始化器是(),则对象是值初始化的。


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

    ——如果 T 是一个(可能是 cv 限定的)类类型 ...

    ——如果 T 是(可能是 cv 限定的)非联合类类型 ...

    ——如果T是一个数组类型,那么每个元素都是值初始化的;

    否则,对象被零初始化。


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

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

    【讨论】:

    • 我已经阅读了文档的那部分,但我不确定其中的含义。对于像 size_t 这样的整数类型,“默认构造”是什么意思? (你能引用一个标准吗?)
    • @Suma:整数类型不是类类型,所以它们没有构造函数。对这些类型进行值初始化等于零初始化。 (第 8 章。)
    • @KerrekSB 您确定您没有将 C++ 与 Java 混淆吗?内置函数不会默认构造为零。
    • @spraff:值初始化需要归零,标准在这里保证值初始化。在 general 中,内置函数保持原样,但在 STL 容器的特殊情况下,它们是值初始化的。同样,如果您调用 std::vector&lt;int&gt; v(10);,您将获得 10 个零。
    • @spraff:值初始化是 C++03 中的新功能(C++98 的少数更改之一)。
    【解决方案2】:

    有什么区别?类类型对象的值初始化需要默认构造,因此答案是“两者”。对于地图&lt;K, V&gt;,新对象将被初始化为V()

    所有标准容器都使用值初始化或直接初始化(后者可能通过复制构造)来初始化新元素。新的标准容器元素不可能处于“未初始化”状态(即没有默认-初始化元素的机制)。

    【讨论】:

    • 我在某种意义上假设“构造”,例如当我在类中使用 int 成员变量时,默认的类构造函数不会初始化该值。我想你是对的,但是“默认构造”短语是否保证了值初始化?如果 V 是 POD 怎么办?它是默认构造(即未初始化)还是值初始化?
    • @Suma: V 是值初始化的,所以如果V 是基本的,它是零初始化的,如果它是类类型的,它是默认构造的。对于复合类型,您可以递归地应用规则。
    猜你喜欢
    • 1970-01-01
    • 2020-10-20
    • 2020-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-03
    • 2013-03-22
    相关资源
    最近更新 更多