为什么 rel_ops 需要相等? “
a==b => !(a<b) && !(b<a)
因为这通常不是真的。如果rel_ops 仅适用于遵循该逻辑的关系运算符,那将是相当有限的。
我猜您想到的是关联容器的 < 运算符所需的弱排序。来自cppreference:
标准库在任何地方使用比较要求,
唯一性是通过使用等价关系确定的。在
不精确的术语,两个对象 a 和 b 被认为是等价的(不是
唯一)如果两者的比较都不小于另一个: !comp(a, b) &&
!comp(b, a)。
简单来说:两个键是否被认为是“相同的”,仅通过要求! (a < b) && ! (b < a)来确定。因此,您只需要为关联容器提供<,而不需要operator== 来确定两个键是否相同。但是,等价 (!(a<b)&&!(b<a)) 不一定与等价 (a==b) 相同。
例如当你使用这个时
struct my_key {
int a;
int b;
bool operator< (const key_type& other) {
return a < other.a; // not comparing b !
}
};
作为std::map 的键,my_key{1,0} 和my_key{1,2} 是等价的(“相同的键”),即使它们不相等。再举一个例子,考虑球坐标中的Point,当a 比b 更接近原点时,我们选择使用a < b:
struct Point {
double radius;
double angle;
bool operator<(const Point& other) {
return radius < other.radius;
}
bool operator==(const Point& other) {
return (radius == other.radius) && (angle == other.angle);
}
}
这里所有三个a < b、b < a 和a == b 可以同时为假。
还要注意(来自cppreference)
从 C++20 开始,std::rel_ops 被弃用,取而代之的是 operator。
对于starship operator <=>,您可以选择
std::strong_ordering
std::weak_ordering
std::partial_ordering
std::strong_equality
std::weak_equality
弱排序是例如std::map(例如my_key 或Point)所需要的,而对于强排序,等价性和相等性基本相同。有关更多详细信息和示例,请参阅this。