为什么 std::rel_ops 需要相等运算符?

Why does std::rel_ops need equality operator?

为什么 rel_ops 需要平等? "<" 还不够吗?

a==b => !(a<b) && !(b<a)

这可能是一个非常愚蠢的问题。我错过了什么吗?

Why is equality needed for rel_ops? Isn't "<" enough?

a==b => !(a<b) && !(b<a)

因为一般情况下并非如此。如果 rel_ops 仅适用于遵循该逻辑的关系运算符,那将是相当有限的。

我猜您想到的是关联容器的 < 运算符所需的弱排序。来自 cppreference:

Everywhere the standard library uses the Compare requirements, uniqueness is determined by using the equivalence relation. In imprecise terms, two objects a and b are considered equivalent (not unique) if neither compares less than the other: !comp(a, b) && !comp(b, a).

简单来说:两个键是否被认为是 "same" 仅通过要求 ! (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} 是等价的 ("same key"),即使它们不相等。作为另一个例子,考虑球坐标中的 Point,当 ab:

更接近原点时,我们选择 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 < bb < aa == b 也可以同时为 false。

另请注意(来自 cppreference

As of C++20, std::rel_ops are deprecated in favor of operator<=>.

对于 starship operator <=> 你可以选择

std::strong_ordering 
std::weak_ordering
std::partial_ordering
std::strong_equality 
std::weak_equality  

弱排序是std::map(例如my_keyPoint)所需要的,而强排序等价和相等性基本相同。有关更多详细信息和示例,请参阅 this.

是的,实际上你错过了某事。这是非常基本的。它与 C++ 或编程无关。这是关于数学的。根据数学,当且仅当“<”在其操作数域上定义了严格的 weak ordering 时,您的陈述才是正确的。并非每个具有 "less" rel_op 的用户定义类型都具有弱排序。