链式相等的运算符重载

时间:2016-05-27 12:03:30

标签: c++ operator-overloading

我想添加一个选项,对MyClass的对象进行链式比较。例如:

MyClass one;
MyClass two;
MyClass three;
/*....*/
if (one == two == three){
    /*....*/
}

如果一切相等,它将返回true,否则它将返回false。 我目前有这个运算符重载,只比较MyClass的两个实例时才能正常工作:

bool operator==(const MyClass &other);

我理解one==two==three等于((one==two)==three)所以我想这应该会改变我的operator==

MyClass& operator==(const MyClass &other);

但我无法理解如何完成此操作,以便能够连续比较两个以上的实例(链式)。

2 个答案:

答案 0 :(得分:4)

正如评论中指出的那样,以这种方式打破通常的语义并不好。如上所述,应遵循Principle of least Astonishment

  

但我无法理解如何完成此操作,以便能够连续比较两个以上的实例(链式)。

并非我认为这样做 1 真的是一个好主意,但这是一个有效的解决方案:

#include <iostream>

using namespace std;

class MyClass {
public:
     MyClass(int x_) : x(x_), isfalse(false) {}

     const MyClass& operator==(const MyClass& rhs) const {
         if(!isfalse && x == rhs.x) {
             return rhs;
         }
         return FalseInst;
     }
     operator bool() const {
         return !isfalse;
     }
private:
     int x;
     MyClass() : x(), isfalse(true)  {}
     const bool isfalse;
     static MyClass FalseInst;
};

MyClass MyClass::FalseInst;
int main()
{
    MyClass one(1);
    MyClass two(1);
    MyClass three(1);

    if(one == two == three) {
        cout << "Yay!" << endl;
    }

    MyClass four(1);
    MyClass five(0);
    MyClass six(0);

    if(!(four == (five == six))) {
        cout << "Yay!" << endl;
    }
}

Live Demo

1) 注意编译器发出的警告。

答案 1 :(得分:3)

作为纯理论问题,这是一种解决方法:

#include <iostream>
using namespace std;

class A {
public:
    int x;

    A(int x = 0) : x(x) {}

    struct Cmp {
        const A *ptr;
        mutable bool val;

        operator bool() const {
            return val;
        }

        const Cmp &operator == (const A &other) const {
            return other == *this;
        }
    };

    bool isEqualTo (const A &other) const {
        return x == other.x;
    }

    Cmp operator == (const A &other) const {        
        return {this, isEqualTo(other)};
    }

    const Cmp &operator == (const Cmp &other) const {
        //other.val = other.val && (*this == *other.ptr).val;
        other.val &= other.ptr->isEqualTo(*this);
        return other;
    }
};

int main() {
    cout << (A(10) == A(10) == A(10)) << endl;
    cout << (A(10) == A(9) == A(10)) << endl;

    return 0;
}