【问题标题】:Can I rely on the order of an unordered map?我可以依赖无序地图的顺序吗?
【发布时间】:2016-04-07 13:33:24
【问题描述】:

我有一个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 存储东西的订单有什么看法?如果没有,最好的选择是什么?

【问题讨论】:

  • 你会得到first 1libc++

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


【解决方案1】:

差不多了。

[C++14: 24.2.5/6]: [..] 在支持等效键的容器中,具有等效键的元素在容器的迭代顺序中是相邻的。因此,虽然未指定无序容器中元素的绝对顺序,但它的元素被分组到等效键组中,这样每个组中的所有元素都具有等效键。 除非另有说明,否则无序容器上的变异操作应保留每个等效键组中元素的相对顺序。

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

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

所以:

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

这与有序的关联容器相反:

[C++14: 23.2.4/4]: 对于多重集和多重映射,插入、放置和擦除保留等效元素的相对顺序。

【讨论】:

  • 但是没有指定新元素的插入位置。如果您在等效键组中有a, b, c,并插入d,则abc 的相对顺序不会改变,但您可以在任何一个中插入d四个地方。
  • @T.C.哪个可能没问题
【解决方案2】:

std::unordered_multimap 既不是有序的(显然)也不是稳定的。因此,您将等效元素放入 std::unordered_multimap 的顺序无法保证与标准一致。

【讨论】:

  • 该措辞暗示了高度的稳定性。
  • @LightnessRacesinOrbit 等效元素仅保证在迭代顺序的连续子范围内。
  • @P​​​​​​​​​​​aulEvans 我知道。
猜你喜欢
  • 1970-01-01
  • 2020-07-22
  • 2017-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-02
  • 2020-12-14
  • 2021-01-08
相关资源
最近更新 更多