两个相同的unordered_maps的顺序是否相同?

时间:2012-03-24 23:23:31

标签: c++ c c++11 unordered-map unordered-set

换句话说,如果我填充两个unordered_mapunordered_set对象具有完全相同的内容和相同的散列函数,那么迭代它们会给出相同的键/值对序列吗?

如果是这样,那么它的条件是什么(例如相同的散列函数,相同的键,不一定是相同的值)。

4 个答案:

答案 0 :(得分:5)

没有。例如,没有要求具有相同散列的对象以任何特定顺序放置。事实上,一般来说,无序地图不可能这样做,因为它可以访问的唯一信息是哈希值。

答案 1 :(得分:4)

此情况下的行为未定义。因此,在某些情况下,序列将是相同的,在其他情况下 - 不同。你什么都不能确定。您提到的类型名为无序,不是偶然的。使用它们作为有序的是非常非常糟糕和非常危险的风格。

您可以发现您的编译器以您想要使用的特殊方式运行。但你不能确定。你一定不能确定!你不知道,什么条件导致编译器的这种行为。您永远无法确定编译器版本的任何更改都不会改变您所需的行为。

在C / C ++中没有指定其他语言中禁止的内容。但你也应该把它视为禁止。

c-faq about the problem of undefined behavior这个概念适用于所有C / C ++

答案 2 :(得分:2)

首先我会引用MSDN

  

受控序列中元素的实际顺序取决于散列函数,比较函数,插入顺序,最大加载因子和当前桶数。您通常无法预测受控序列中元素的顺序。但是,您始终可以确信,具有等效排序的任何元素子集在受控序列中都是相邻的。

unordered_mapunordered_set的上述引用相同,并且名称暗示序列未指定,但是,它们确实提到等效键是相邻的。

答案 3 :(得分:0)

如果您需要保证订购,那么您的数据结构。事实上,如果您主要要进行迭代,unordered_map/set也不是您的数据结构。

对于迭代,std::map将被证明是更好的数据结构,因为从一个节点到下一个节点的gonig在算法上更复杂。并且std::map 中对象的迭代顺序由规范保证(实际上是结构本身的定义属性)。 (显然,这是假设您使用相同的比较运算符)。 std::map中没有涉及散列。

可以说,听起来你在这里咆哮着错误的树。 unordered_map通常应该用于诸如O(1)查找之类的好处,而不是用于存储对象列表然后迭代它们。如果你想要获得一个确定的迭代顺序,那么绝对不应该被使用。