【问题标题】:Why does std::rel_ops need equality operator?为什么 std::rel_ops 需要相等运算符?
【发布时间】:2019-07-10 12:00:46
【问题描述】:

为什么 rel_ops 需要相等? “

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

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

【问题讨论】:

  • 好吧,如果标准这样做了,它将使 NaN 等于 NaN,这是值得商榷的......不,你不能完全将它与 std::map 的发现方式进行比较关键。因为key has 约束的域
  • 不完全关于rel_ops,但这是&lt;=&gt; 的热门话题。您可以在论文 (&lt;=&gt; != ==, I did not order this! Why is it on my bill?) 和博客 (Improvements to <=>) 中阅读更多内容。作为参考,&lt;=&gt; 已因此而更改。
  • @chris:谢谢!非常有趣的阅读

标签: c++ operators std equality


【解决方案1】:

是的,实际上你错过了什么。这是非常基础的。它与 C++ 或编程无关。这是关于数学的。根据数学,当且仅当“weak ordering 时,您的陈述才是正确的。并非每个带有“less”rel_op 的用户定义类型都具有弱排序。

【讨论】:

    【解决方案2】:

    为什么 rel_ops 需要相等? “

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

    因为这通常不是真的。如果rel_ops 仅适用于遵循该逻辑的关系运算符,那将是相当有限的。

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

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

    简单来说:两个键是否被认为是“相同的”,仅通过要求! (a &lt; b) &amp;&amp; ! (b &lt; a)来确定。因此,您只需要为关联容器提供&lt;,而不需要operator== 来确定两个键是否相同。但是,等价 (!(a&lt;b)&amp;&amp;!(b&lt;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,当ab 更接近原点时,我们选择使用a &lt; 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 &lt; bb &lt; aa == b 可以同时为假。

    还要注意(来自cppreference

    从 C++20 开始,std::rel_ops 被弃用,取而代之的是 operator。

    对于starship operator &lt;=&gt;,您可以选择

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

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

    【讨论】:

    • @LightnessRacesinOrbit 我不记得我为什么把它放在那里,它与示例无关。
    • 这也不是真的 :)
    • @LightnessRacesinOrbit 是的,我知道 ;),这不是最好的例子,我仍然想保留它
    • 感谢您的回答!实际上,我从需要 std::map 的任务开始对此感到疑惑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-19
    • 2023-01-11
    • 2012-08-10
    • 2021-11-16
    • 1970-01-01
    相关资源
    最近更新 更多