这个班级是否会有严格的弱序

时间:2011-08-18 04:39:35

标签: c++ math stl

说我有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为false,但bar < bazbaz < bar也是如此。

请注意,此处的排序完全忽略b,但b是等式关系的一部分。

3 个答案:

答案 0 :(得分:12)

技术上是的,您是由a成员直接订购它们,这对于例如。 std::set。基本上它们表现得像整数,即。如果a&lt; b和b&lt;然后a&lt; c等。我不认为operator ==会影响运算符隐含的排序的有效性&lt;。

但是 - 在同一个类上定义两个操作符是一个坏主意,这意味着它有不同的东西,因为它可能会使该类的用户感到困惑。据我所知,它不会直接破坏任何STL容器,因为它们只使用两个运算符中的一个,但它肯定会让我感到困惑,你可以将这个案例放在哪里!(bar&lt; baz)和!(baz&lt;吧)但是!(bar == baz)。

在这种情况下,我更愿意仅提供对该类更自然的运算符,并通过可作为模板参数提供给STL容器的独立结构使另一个可用。对我而言,它更清楚地表明它是一种排序类的实例的方式,它不一定等同于其他成员操作符。

答案 1 :(得分:4)

根据strict weak ordering上的维基百科条目,它具有以下属性:

  
      
  • 对于所有x,不是x&lt; x(反射性)。
  •   
  • 对于所有x≠y,如果x <那么y&lt; X   (非对称)。
  •   
  • 对于所有x,y和z,如果x&lt; y和y&lt; z然后x&lt; z(及物性)。
  •   
  • 对于所有x,y和z,如果x与y无法比较,则y为   与z无法比较,那么x与z无法比较(传递性为   等价)。
  •   
您的类的

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

然而,正如彼得在他的answer中提到的那样,定义operator==时考虑到额外的成员变量会导致不直观的结果,这可能会使您的班级用户感到困惑。

答案 2 :(得分:0)

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