std:map 如何检查两个对象是否相等?

How does std:map check whether two objects are equal?

即使我在地图中插入了两个元素,为什么以下代码会打印 1

#include <iostream>
#include <map>
#include <string>
#include <utility>

struct Foo
{
  Foo(int bar, const std::string& baz)
    : bar(bar)
    , baz(baz)
  {}

  int bar;
  std::string baz;

  bool operator<(const Foo& rhs) const
  {
    if (bar < rhs.bar && baz < rhs.baz)
    {
      return true;
    }
    else
    {
      return false;
    }
  }
};

int main()
{
    Foo first(0, "test");
    Foo second(1, "test");
    std::map<Foo, std::string> m;
    m.insert(std::make_pair(first, "test"));
    m.insert(std::make_pair(second, "test1"));
    std::cout << m.size() << std::endl;
}

第二次调用 insert() 表示我们已经在地图中找到了该项目。为什么?

我的previous question因为打字错误被错误关闭了。我知道 insert 会告诉您该物品是否已经在容器中。

地图的 insert() 使用您提供的 operator< 来决定元素之间的等价性。如果 a < bb < a 都为假,则认为这两个元素相等。

您的 operator<() 不一致,因为它没有定义必要的 strict weak ordering。例如,考虑 a.bar < b.barb.baz < a.baz;那么 a < b 是假的,b < a 是假的,所以地图相信 a == b.

在你的具体情况下,当比较firstsecond时,first.bazsecond.baz都是"test",所以两个比较return false,元素被认为是相等的。

你需要这样的东西:

bool operator<(const Foo& rhs) const
{
    return std::tie(bar, baz) < std::tie(rhs.bar, rhs.baz);
}