在C++中为不同类型重载比较运算符

9

我需要将一个包含多个属性的类与整数进行比较,尽管这可能有点伸缩相等性的定义,但足够接近...

如何为不同类型重载相等运算符?

我基本上有一个像这样的类

struct MyClass {
    int start;
    int middle;
    int threequarters;
};

以及重载运算符

inline bool operator==(const MyClass& lhs, const MyClass& rhs) {
    return lhs.middle == rhs.middle;
}

因此,在与整数进行比较时,我需要同时与中间变量进行比较,但我不确定是否需要两组操作函数,一组是左手边是整数,另一组则是右手边是整数?

inline bool operator==(const int& lhs, const MyClass& rhs) {
    return lhs == rhs.middle;
}

inline bool operator==(const MyClass& lhs, const int& rhs) {
    return lhs.middle == rhs;
}

1
是的,你应该以这种方式做 - 支持(int,MyClass)和(MyClass,int)。虽然你可以用其中一个运算符来定义另一个运算符。另一种可能性是为MyClass设置一个从int构造的构造函数 - 然后你只需要一个operator(MyClass,MyClass),因为当编译器遇到int时,它可以将其提升为类型MyClass,以便operator进行操作。 - qeadz
那么,为了比较MyClass和MyClass,以及整数和MyClass,我需要每个比较函数的3个集合(总共18个),即使其中大多数将引用其他函数..? - user3235200
2
或者给你的类一个转换构造函数 MyClass(int i) : middle(i) {} - juanchopanza
重载比较运算符,使其不比较对象的所有部分,对我来说似乎是一种不好的做法。如果你想要这样的函数,我更喜欢定义一个名字描述它所做的事情的函数,例如 bool areEqualAtMiddle(const MyClass& lhs, const MyClass& rhs) - Chris Drew
@ChrisDrew 是的,我知道,只是我将这些 MyClass 存储在一个集合中,在执行过程中某些时候我只能访问中间值,所以我需要想办法重新获取引用... - user3235200
3个回答

8
为了澄清我的评论,这将支持代码,因此您可以提供所有运算符的变体:
inline bool operator==(const MyClass& lhs, const MyClass& rhs) {
return lhs.middle == rhs.middle;
}

inline bool operator==(const int& lhs, const MyClass& rhs) {
return lhs == rhs.middle;
}

inline bool operator==(const MyClass& lhs, const int& rhs) {
return lhs.middle == rhs;
}

对于每个运算符都要执行此操作(这将导致大量的代码)。或者,如果有意义的话,您可以提供一个从int构造的构造函数:

struct MyClass {
MyClass() {} // default
MyClass( int x ) { /* init for an int here */ }
int start;
int middle;
int threequarters;
};

如果您这样做,那么每个运算符只需要MyClass、MyClass版本即可:
inline bool operator==(const MyClass& lhs, const MyClass& rhs) {
return lhs.middle == rhs.middle;
}

因为当编译器看到:

if ( 5 == my_class ) {}

它实际上是这样做的:
if ( MyClass(5).operator==( my_class ) ) {}

1

是的,如果你的类没有为int类型的对象定义转换构造函数,则需要定义三个operator ==。

inline bool operator==(const MyClass& lhs, const MyClass& rhs) {
    return lhs.middle == rhs.middle;
}

inline bool operator==(const MyClass& lhs, int rhs) {
    return lhs.middle == rhs;
}

inline bool operator==(int lhs, const MyClass& rhs) {
    return operator ==( rhs, lhs );
}

我不应该使用... const int& rhs ...吗? - user3235200
1
@user3235200 不需要使用 const int &。使用 int 就足够好了。 - Vlad from Moscow

0

是的,你需要两个运算符。

bool operator==(const A& a, const int & b)
{
    return a.value == b;
};

只定义了上述运算符,如果您尝试以下操作:2 == a(假设类A没有将整数作为参数的隐式构造函数),编译器将抛出错误,表示没有可用的转换。

对于每个二元操作,编译器都会尝试进行隐式转换以适应操作。例如,如果class A有一个operator int定义,则不需要这些运算符,因为编译器会隐式地将A类型转换为整数,然后执行bool operator==(int,int)操作。如果未定义运算符,则编译器会抛出错误,表示没有可用的转换(即,在左侧或右侧没有接受A作为参数的运算符==)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接