为什么C++ STL 容器使用 "less than" 运算符<而不是 "equal equal" 运算符== 作为比较器?

Why C++ STL containers use "less than" operator< and not "equal equal" operator== as comparator?

本文关键字:运算符 equal 比较器 STL C++ 为什么 than less lt      更新时间:2023-10-16

在自定义类中实现比较器运算符时,std::map,我遇到了这个问题,看不到任何地方被问到。

除了上述问题外,还有兴趣简要了解operator<如何为std::map工作。

问题的起源:

struct Address {
  long m_IPv4Address;
  bool isTCP;
  bool operator< (const Address&) const;  // trouble
};

std::map<K,D>需要能够排序。 默认情况下使用 std::less<K> ,对于非指针,使用 < 1

使用你对用户要求最少的规则,它在需要时从<合成"等价"(!(a<b) && !(b<a)意味着ab是等价的,即,两者都不小于另一个)。

这使得编写类作为map的关键组件更容易,这似乎是一个好主意。

std容器使用==例如 std::unordered_map ,它使用 std::hash== 。 同样,它们的设计使得它们对用户的要求最少——你不需要完全订购unordered_容器,只需要等效和良好的hash

碰巧的是,如果您可以访问<,则编写<tuple>真的很容易。

struct Address {
  long m_IPv4Address;
  bool isTCP;
  bool operator< (const Address& o) const {
    return
      std::tie( m_IPv4Address, isTCP )
      < std::tie( o.m_IPv4Address, o.isTCP );
  }
};

它使用<tuple>中定义的std::tie为您生成适当的<std::tie获取一堆数据,并生成一tuple引用,其中已经定义了良好的<


1 对于指针,它使用一些与指定<行为的<兼容的比较,并且在未指定<行为时表现良好。 这只对分段内存模型和其他晦涩的架构真正重要。

因为std::map是一个排序的关联容器,所以它的键需要排序。

==操作员不允许订购多个密钥

您可能正在寻找std::unordered_map,其中工作具有哈希表。您可以指定自己的哈希和相等运算符函数:

explicit unordered_map( size_type bucket_count,
                    const Hash& hash = Hash(),
                    const KeyEqual& equal = KeyEqual(),
                    const Allocator& alloc = Allocator() );

使用<您可以对元素进行排序。如果a < ba应放在集合中的b之前。

您还可以确定两个项目是否等效:如果!(a < b) && !(b < a)(如果两个对象都不比另一个对象小),则它们是等效的。

这两个功能都是std::map需要的。因此,它只期望其元素类型提供运算符<

使用==可以确定相等性,但无法对元素进行排序。所以它不会满足std::map的要求。