C++ 链式等运算符重载

C++ 链式等运算符重载,c++,operator-overloading,C++,Operator Overloading,我想添加一个选项,对MyClass的对象进行链式比较。例如: MyClass one; MyClass two; MyClass three; /*....*/ if (one == two == three){ /*....*/ } 因此,如果所有值相等,它将返回true,否则它将返回false。 当前,当只比较两个MyClass实例时,我的运算符重载运行良好: bool operator==(const MyClass &other); 我知道one==two==thre

我想添加一个选项,对
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)
,所以我想应该将我的
操作符==
更改为类似于:

MyClass& operator==(const MyClass &other);
但我无法理解如何完成这项工作,以便能够比较一行中的两个以上实例(链接)。

作为一个纯粹的理论问题,这里有一种解决方法:

#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;
}
#包括
使用名称空间std;
甲级{
公众:
int x;
A(intx=0):x(x){}
结构Cmp{
常数A*ptr;
可变布尔值;
运算符bool()常量{
返回val;
}
常量Cmp和运算符==(常量A和其他)常量{
返回other==*这个;
}
};
布尔·伊斯夸尔托(常数A和其他)常数{
返回x==other.x;
}
Cmp运算符==(常数A和其他)常数{
返回{此,isEqualTo(其他)};
}
常量Cmp和运算符==(常量Cmp和其他)常量{
//other.val=other.val&(*this===*other.ptr).val;
other.val&=other.ptr->isEqualTo(*此项);
归还他人;
}
};
int main(){

cout正如评论中所指出的那样,以这种方式打破通常的语义是不好的。正如前面提到的,应该遵循

但我无法理解如何完成此操作,以便能够比较一行中的两个以上实例(链接)

我并不认为执行so1是一个好主意,但这里有一个可行的解决方案:

#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;
#包括
使用名称空间std;
类MyClass{
公众:
MyClass(intx_uux):x(x_ux),isfalse(false){
常量MyClass和运算符==(常量MyClass和rhs)常量{
如果(!isfalse&&x==rhs.x){
返回rhs;
}
返回错误;
}
运算符bool()常量{
返回!是假的;
}
私人:
int x;
MyClass():x(),isfalse(true){}
常数布尔为假;
静态MyClass Falsinst;
};
MyClass MyClass::FalseInst;

intmain()
{
第一类(1);
第二类(1);
第三类(1);
如果(一==二==三){

为什么不遵循正常的语义并使用
如果(1==2&&2==3)
?请不要。@NathanOliver:的确,“EqualExpr”对象必须计算所有等式,而正常的语义可能会短路。你说的“让它工作”是什么意思?
(1==2)==three
在语义上并不等同于
one==three&&two==three
.1)。以奇怪和意外的方式进行操作会导致用户体验/支持出现问题。2)提供一个具有实际帮助和自我解释名称的帮助函数。编辑:回答此评论↓非常令人印象深刻的解决方案,开销最小。虽然
one==(two==three)
three
为另一个值来打破它:)现在
one==two==three
two
three
0
@coyotte508,它实际上是不可合理解决的。
if(x==rhs.x)
->
如果(!isfalse&&x==rhs.x)
--对不起,我被你的答案和给我留下深刻印象的
静态
成员迷住了:)
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;
    }
}