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

Why does std::rel_ops need equality operator?

提问人:Radu C 提问时间:2/16/2019 更新时间:2/17/2019 访问量:113

问:

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

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

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

C++ 运算符 std 相等

评论

2赞 WhiZTiM 2/16/2019
好吧,如果标准这样做了,它将使诸如 等于 的东西,这是值得商榷的......不,您无法将其与查找密钥的方式进行完全比较。因为密钥的域约束NaNNaNstd::map
2赞 chris 2/17/2019
不完全是关于,但这一直是 .您可以在论文中阅读更多内容 (<=> != ==我没有订购这个!为什么它出现在我的账单上?和博客(对 <=> 的改进)。作为参考,已经因此而更改。rel_ops<=><=>
0赞 Radu C 2/19/2019
@chris:谢谢!非常有趣的阅读

答:

2赞 463035818_is_not_an_ai 2/17/2019 #1

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

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

因为这在一般情况下是不正确的。如果只适用于遵循该逻辑的关系运算符,那么它将受到相当大的限制。rel_ops

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

在标准库使用“比较”要求的任何地方, 唯一性是通过使用等价关系来确定的。在 不精确的术语,两个对象 a 和 b 被认为是等价的(不是 unique),如果两者都不比另一个少:!comp(a, b) && !comp(b, a)。

简单来说:两个密钥是否被认为是“相同”的,只能通过要求来确定。因此,您只需要为关联容器提供 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 !
    }
};

作为 then 和 are 等价的键(“同一键”),即使它们不相等。再举一个例子,考虑一个球面坐标,我们选择在哪个球面坐标中,当时间更接近原点时:std::mapmy_key{1,0}my_key{1,2}Pointa < bab

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

另请注意(来自 cppreference)

自 C++20 起,不推荐使用 std::rel_ops,取而代之的是 operator<=>。

对于星际飞船操作员<=>您可以选择

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

弱排序是必需的,例如(例如或),而对于强排序,等价和相等基本相同。有关更多详细信息和示例,我建议您参考std::mapmy_keyPoint

评论

0赞 463035818_is_not_an_ai 2/17/2019
@LightnessRacesinOrbit我不记得我为什么把它放在那里,它与示例无关。
0赞 Lightness Races in Orbit 2/18/2019
这也不是真的:)
0赞 463035818_is_not_an_ai 2/18/2019
@LightnessRacesinOrbit是的,我知道;),这不是最好的例子,但我仍然想保留它
0赞 Radu C 2/19/2019
谢谢你的回答!我实际上从需要std::map的任务开始想知道这个问题。
1赞 Red.Wave 2/17/2019 #2

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