【问题标题】:Overloading comparison operators for different types in c++重载C++中不同类型的比较运算符
【发布时间】:2026-01-17 02:10:01
【问题描述】:

我需要能够将我的一个类(它包含的远不止一个整数)与整数进行比较,即使这可能会稍微扩展相等性,但它已经足够接近了......

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

我基本上都有这样的课

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

和重载的运算符

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

所以当与整数进行比较时,我还需要与中间变量进行比较,但我不确定我是否需要两组运算符函数,一组整数是 lhs,一组整数是 rhs?

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,MyClass) 和 (MyClass,int)。尽管您可以根据另一个运算符来定义其中一个运算符。另一种可能性是有一个 MyClass 的构造函数,它从 int 构造 - 然后你只需要一个 operator(MyClass,MyClass) 因为当编译器遇到 int 时,它可以将它提升为运算符的 MyClass 类型。
  • 所以要比较 MyClass 和 MyClass,以及整数和 MyClass,我需要每个比较函数 3 组(总共 18 个),即使它们中的大多数会引用其他函数..?
  • 或者给你的类一个转换构造函数MyClass(int i) : middle(i) {}
  • 重载比较运算符以使其不比较对象的所有部分对我来说似乎是不好的做法。如果你想要这样的函数,我宁愿只定义一个函数,其名称描述它的作用,例如bool areEqualAtMiddle(const MyClass& lhs, const MyClass& rhs)
  • @ChrisDrew 是的,我知道,只是我将这些 MyClass 存储在一个集合中,并且在执行期间的某些时候我只能访问中间值,所以我需要取回引用不知怎的……

标签: c++ operator-overloading comparison-operators


【解决方案1】:

为了澄清我的评论,这将支持代码,因此您可以提供所有运算符的变体:

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 ) ) {}

【讨论】:

    【解决方案2】:

    是的,您需要定义三个运算符 ==,前提是您的类没有用于 int 类型对象的转换构造函数。

    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 不,没有任何必要使用 const int &。使用 int 就足够了,而且更好。
    【解决方案3】:

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

    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 作为左侧或右侧的参数)

    【讨论】: