比较器 - 重载运算符<

时间:2013-05-18 04:07:24

标签: c++ visual-c++ operator-overloading set

我正在尝试使用std::set来包含三个成员变量的结构。

 struct blah{
       int  a,b,c;
       bool operator < ( const blah& blo  ) const{
           return ( a < blo.a || (a == blo.a && (b != blo.b || c != blo.c ) ) );
       }
 };

但我一直收到一个错误,我的运营商&lt;是无效的。我的做法有什么问题? enter image description here

    struct blah {
           int  a,b,c;
                blah(int aa,int bb,int cc){ a=aa; b=bb; c=cc; }
           bool operator < ( const blah& blo  ) const{
               return ( a < blo.a 
                              || (a == blo.a && b < blo.b  )
                              || (a == blo.a && b == blo.b && c < blo.c  ) 
                      );
           }
     };

    int main() {
            std::set<blah> st;

            st.insert(blah(1,2,3));
            st.insert(blah(1,1,1));
            st.insert(blah(1,3,2));
            return 0;
    }

在更改@paxdiablo代码之后的代码后,这很有效。谢谢你们!

1 个答案:

答案 0 :(得分:4)

在以下完整程序中,代码编译对我来说很好:

#include <iostream>

struct blah {
       int  a,b,c;
       bool operator < ( const blah& blo  ) const{
           return ( a < blo.a || (a == blo.a && (b != blo.b || c != blo.c ) ) );
       }
 };

int main (void) {
    blah x, y;
    x.a=2; x.b=2; x.c=2;
    y.a=2; y.b=2; y.c=2;
    if (x < y) std::cout << "x<y\n";
    if (y < x) std::cout << "x>y\n";
    if (!(y < x) && !(x < y)) std::cout << "x=y\n";
    return 0;
}

更改xy的字段会输出不同的消息。

但我发现这个功能存在一个主要问题。在两个x < y字段相同但y < x字段不同的情况下,它可以告诉您a b二。如果您将两个a字段设置为1并将b字段设置为21,则会看到:

x<y
y<x

这不会很好地结束: - )

您所获得的是调试断言(专门用于捕获大多数调试代码中的运行时错误的内容)这一事实使我相信运行时库可能通过检测来明确检查错误的operator<重载后一种情况(即x < y y < x都是真的。)

你应该真的解决这个问题,因为它会导致集合出现各种各样的问题,例如你需要对事物进行排序。

举例来说,假设您希望使用abc作为该优先级的关键字。执行此操作的功能将包含以下内容:

// Check primary key.

if (a < blo.a) return true;
if (a > blo.a) return false;

// Primary key equal here, use secondary key.

if (b < blo.b) return true;
if (b > blo.b) return false;

// Primary and secondary keys equal here, use tertiary key.

return (c < blo.c);