std::unordered_map初始化

12

当我首次使用 std::unordered_map 的 operator [] 访问元素 时,它会自动创建。关于其初始化,有哪些保证 (如果有的话)? (保证进行值初始化,还是只保证构造?)

示例:

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

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

2个回答

29
在这个序列的结尾,size[test]的大小被保证为10。 在您的代码的最后一行中,size [test]将元素值初始化为T(),或在这种情况下为size_t():
C++11 23.4.4.3映射元素访问[map.access] T&operator [](const key_type&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;

@Suma:整数类型不是类类型,因此它们没有构造函数。对这些类型进行值初始化等同于零初始化。(第8章。) - Kerrek SB
@KerrekSB 你确定你没有把C++和Java搞混吗?内置类型不会默认构造为零。 - spraff
什么鬼?这是C++11的新特性吗?我确定内建函数没有默认值,符合无额外开销原则。 - spraff
1
@spraff:值初始化意味着将其清零,并且标准保证在此处进行值初始化。通常情况下,内置类型保持不变,但在STL容器的特殊情况下,它们会进行值初始化。同样地,如果你调用 std::vector<int> v(10);,你将获得10个零。 - Matthieu M.
1
@spraff:在C++03中,值初始化是新的语法(相较于C++98只有极少数变化)。 - Mike Seymour
显示剩余4条评论

0

有什么区别?类类型对象的值初始化涉及默认构造,因此答案是“两者都是”。对于一个映射 <K, V>,新对象将用 V() 初始化。

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


我理解中的“constructed”是指当我在类中使用int成员变量时,默认的类构造函数不会初始化该值。我想你是对的,但“default constructed”这个短语是否保证了值初始化呢?如果V是POD类型,那么它会被默认构造(即未初始化)还是值初始化呢? - Suma
@Suma:V是值初始化,所以如果V是基本类型,它将被零初始化;如果它是类类型,则会进行默认构造。对于复合类型,您需要递归地应用这些规则。 - Kerrek SB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接