如何了解两个 std::multimap 是否具有相同的内容?

How to learn if two `std::multimap`s have the same contents?

我不得不承认我从来没有对标准库进行过适当的研究,但这让我感到惊讶

#include <iostream>
#include <map>

int main (int argc, char ** argv)
{
    std::multimap<int, int> mm1;
    mm1.insert( std::pair<int, int>(0, 0) );
    mm1.insert( std::pair<int, int>(0, 1) );

    std::multimap<int, int> mm2;
    mm2.insert( std::pair<int, int>(0, 1) );
    mm2.insert( std::pair<int, int>(0, 0) );

    std::cout << "The maps are "
          << ( (mm1 == mm2) ? "equal" : "not equal" )
          << std::endl;
}

尝试一下我们得到...

$ g++ --std=c++11 -o multimaporder multimaporder.cc
$ ./multimaporder 
The maps are not equal

因此,您将事物放入地图的顺序很重要。这不是我对关联容器的第一个期望,但很好。

使用随机访问容器,我的下一个计划通常是对它们进行排序然后比较...但是添加

#include <algorithm>
//...
    std::sort( mm1.begin(), mm1.end() );
    std::sort( mm2.begin(), mm2.end() );

    std::cout << "The *sorted* maps are "
              << ( (mm1 == mm2) ? "equal" : "not equal" )
              << std::endl;

只是结果是很多关于找不到一组可接受的迭代器交给 sort 的抱怨。

那么判断两个multimap内容是否相同的正确方法是什么?

Per [associative.reqmts]/4 std::multimap 要求保持等效键的插入顺序,以便两个容器只有在具有相同顺序的相同值时才会比较相等。

如果您不关心顺序,您可以使用不关心顺序的 std::unordered_multimap,只要它们具有相同的值,它们就会相互比较相等

int main (int argc, char ** argv)
{
    std::unordered_multimap<int, int> mm1;
    mm1.insert( std::pair<int, int>(0, 0) );
    mm1.insert( std::pair<int, int>(0, 1) );

    std::unordered_multimap<int, int> mm2;
    mm2.insert( std::pair<int, int>(0, 1) );
    mm2.insert( std::pair<int, int>(0, 0) );

    std::cout << "The maps are "
          << ( (mm1 == mm2) ? "equal" : "not equal" )
          << std::endl;
}

产出

The maps are equal

So, the order you put things into the map matters.

不,地图没关系,但你使用多地图,这是一个不同的野兽。正如 std::multimap::insert()

的文档中所述

1-2) inserts value. If the container has elements with equivalent key, inserts at the upper bound of that range.(since C++11) The overload (2) is equivalent to emplace(std::forward

(value)) and only participates in overload resolution if std::is_constructible::value == true.

重点是我的。所以可能的解决方案:

  • 通过向 std::multimap::insert.
  • 提供适当的提示,将值插入 std::multimap 以在两个容器中保持相同的顺序(例如排序)
  • 使用所有对都完全排序的容器,例如 std::set<std::pair<int,int>> 你应该注意行为上的差异
  • 使用特殊的比较器,它会以某种方式实现不同顺序的值是否相等

请注意,您不能求助 std::multimap 中的元素,将它的迭代器传递给 std::sort,这会破坏容器不变性。

对于这种情况,您需要比较以下集合

bool comp ()
{
    using Map = std::multimap<int, int>;
    Map mm1;
    mm1.insert( std::pair<int, int>(0, 0) );
    mm1.insert( std::pair<int, int>(0, 1) );

    Map mm2;
    mm2.insert( std::pair<int, int>(0, 1) );
    mm2.insert( std::pair<int, int>(0, 0) );


    return std::set<Map::value_type>(mm1.begin(), mm1.end()) == std::set<Map::value_type>(mm2.begin(), mm2.end());
}