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

Gui*_*cot 9 c++ gcc multimap language-lawyer c++11

我有一个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;
}
Run Code Online (Sandbox Code Playgroud)

此代码输出:

last
3
Run Code Online (Sandbox Code Playgroud)

这至少是GCC,我想要的行为.我可以依靠吗?标准是否对std::unordered_multimap商店的订单说了什么?如果没有,最好的选择是什么?

Lig*_*ica 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保留等效元素的相对顺序.

  • 但是没有指定插入新元素的位置.如果在等效键组中有`a,b,c`,并插入`d`,则`a`,`b`和`c`的相对顺序不会改变,但你可以插入`d `在四个地方中的任何一个地方. (4认同)