这个类有严格弱排序吗?

Would this class have a Strict Weak Ordering

本文关键字:排序      更新时间:2023-10-16

假设我有class/struct Foo

struct Foo {
    int a, b;
    bool operator< (Foo const& r){
        return a < r.a;
    }
    bool operator== (Foo const& r){
        return a==r.a&&b==r.b;
    }
};
Foo bar = { 5, 1 };
Foo baz = { 5, 2 };

现在bar == baz是假的,bar < bazbaz < bar也是假的。

请注意,这里的排序完全忽略了b,但b是相等关系的一部分。

技术上是的,您直接通过a成员订购它们,这对于例如应该是好的。std::set。基本上它们表现得像整数,即。如果<c等。我不认为操作符>

然而,在同一个类上定义两个隐含不同含义的操作符是一个坏主意,因为这可能会使该类的用户感到困惑。据我所知,它不会直接破坏任何STL容器,因为它们只使用两个操作符中的一个,但它肯定会让我感到困惑,你可以有这种情况!巴兹)和(巴兹<(Bar == baz).

在这种情况下,我宁愿只提供对类更自然的操作符作为成员,并通过可以作为模板参数提供给STL容器的独立结构体提供其他操作符。对我来说,这更清楚地表明,这是一种排序类实例的方式,不一定等同于其他成员操作符。

根据维基百科关于严格弱排序的条目,它具有以下属性:

  • 对于所有x, x
  • 对于所有x≠y,如果x <那么就不是Y><x(不对称)。>
  • 对于所有x, y和z,如果x <z(传递性)。>
  • 对于所有x, y和z,如果x与y不可比较,则y是与z不可比,则x与z不可比(的及物性)等价)。
您的类的

operator<满足所有这些属性,并且它本身就足以限定为具有严格的弱排序,因为根据定义所需的二进制关系是<,而不是==

然而,正如Peter在他的回答中提到的,定义operator==时考虑到一个额外的成员变量可能会导致不直观的结果,这可能会使您的类的用户感到困惑。

类本身没有弱排序。严格弱序是二进制函数,如operator<(Foo, Foo)。一旦意识到这一点,就很明显为什么函数F不能影响函数G是否是SWO了——它是G的一个独立属性。这就是operator==不能影响operator<是否是SWO的原因。