我可以依赖无序地图的顺序吗?

时间:2016-01-03 23:05:53

标签: c++ c++11 gcc language-lawyer multimap

我有一个std::unordered_multimap,我希望得到特定键的最后一个插入元素。我观察到了这种行为:

#include <iostream>
#include <string>
#include <unordered_map>

using namespace std;

int main() {
    unordered_multimap<string, string> mmap;

    mmap.emplace("a", "first");
    mmap.emplace("a", "second");
    mmap.emplace("a", "last");
    mmap.emplace("b", "1");
    mmap.emplace("b", "2");
    mmap.emplace("b", "3");

    auto last_a = mmap.equal_range("a").first;
    auto last_b = mmap.equal_range("b").first;

    cout << last_a->second << endl;
    cout << last_b->second << endl;

    return 0;
}

此代码输出:

last
3

至少,这是GCC,我想要的行为。我可以依靠吗?标准是否对std::unordered_multimap存储事物的顺序说了什么?如果没有,最好的替代方案是什么?

2 个答案:

答案 0 :(得分:8)

几乎。

  

[C++14: 24.2.5/6]: [..] 在支持等效键的容器中,具有等效键的元素在容器的迭代顺序中彼此相邻。因此,虽然未指定无序容器中元素的绝对顺序,但其元素被分组为等效键组,以使每个组的所有元素具有等效键。 无序容器的变异操作应保留每个等效密钥组中元素的相对顺序,除非另有说明。

     

[C++14: 24.2.5/9]: [..] 对于unordered_multiset和unordered_multimap,rehashing会保留等效元素的相对顺序。

这是非常尴尬的措辞但是,从我所知道的,一般的概念是等效键下面的元素的顺序是未指定的,尽管它之后至少几乎保持不变。

所以:

您不能依赖广告订单,但如果您需要小心,可以依赖稳定的订单。

这与有序关联容器形成对比:

  

[C++14: 23.2.4/4]: 对于multiset和multimap,insert,emplace和erase保留等效元素的相对顺序。

答案 1 :(得分:1)

std::unordered_multimap既没有被命令(显然)也没有稳定。因此,将等效元素放入std::unordered_multimap的顺序绝不能保证符合标准。