为什么C++ STL 容器使用 "less than" 运算符<而不是 "equal equal" 运算符== 作为比较器?
Why C++ STL containers use "less than" operator< and not "equal equal" operator== as comparator?
在自定义类中实现比较器运算符时,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)
意味着a
和b
是等价的,即,两者都不小于另一个)。
这使得编写类作为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 < b
则a
应放在集合中的b
之前。
您还可以确定两个项目是否等效:如果!(a < b) && !(b < a)
(如果两个对象都不比另一个对象小),则它们是等效的。
这两个功能都是std::map
需要的。因此,它只期望其元素类型提供运算符<
。
使用==
可以确定相等性,但无法对元素进行排序。所以它不会满足std::map
的要求。
- 为什么比较运算符如此快速
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 使用C++中的模板和运算符重载执行矩阵运算
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 增量运算符与后缀混淆
- 一个关于在C++中重载布尔运算符的问题
- 运算符C++ "delete []"仅删除 2 个前值
- 模板类无法识别友元运算符
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 关闭||运算符优化
- 通过继承类使用来自不同命名空间的运算符
- C++Cast运算符过载
- 如何使用AngelScript注册SFML Vector2运算符
- 重载元组索引运算符-C++
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 布尔比较运算符是如何在C++中工作的
- 为什么C++ STL 容器使用 "less than" 运算符<而不是 "equal equal" 运算符== 作为比较器?
- if-else 语句中的"equal to"运算符与"not equal to"运算符