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;
}
}