结构体成员函数无法使用默认不等运算符的原因及解决方法
关于C++默认比较运算符的疑问
示例代码
struct Point { int x; int y; auto operator<=> (const Point&) const = default; //bool operator!=(const Point&) const = default; bool isDifferent(const Point& another) const { // 无显式operator!=时编译失败 return operator != (another); } bool isSame(const Point& another) const { // 始终可正常编译 return operator == (another); } }; int main() { Point pt1{1, 1}, pt2{1, 2}; std::cout << std::boolalpha << (pt1 == pt2) << ' ' // 始终可正常编译 << (pt1 != pt2) << ' ' // 始终可正常编译 << (pt1 < pt2) << ' ' << (pt1 <= pt2) << ' ' << (pt1 > pt2) << ' ' << (pt1 >= pt2) << ' '; }
现象说明
使用
==运算符的成员函数isSame可正常编译,使用!=运算符的成员函数isDifferent则报“operator未定义”错误;但在成员函数外部使用!=运算符却可正常运行。
问题
出现该现象的原因是什么?是否可以无需显式定义不等运算符,就能在成员函数内使用它?
原因分析
默认生成规则的差异:
- 当默认定义
<=>运算符时,编译器会自动生成成员版的operator==,所以成员函数里直接调用operator==(another)能找到这个成员函数,编译正常。 - 但
operator!=不会生成成员版,而是依赖全局重载模板实现——这个模板通过!(a == b)完成不等判断。不过该全局模板优先级低于成员函数,在成员函数内部写operator != (another)时,编译器会优先查找类的成员函数,找不到就直接报错,不会匹配全局模板。
- 当默认定义
查找规则的内外差异:
- 在成员函数外部(比如
main中)写pt1 != pt2,编译器会同时查找成员和全局作用域的重载,能匹配到全局的!=模板,因此正常编译。 - 但在成员函数内部,
operator != (another)等价于this->operator!=(another),属于隐式成员函数调用,编译器只会在当前类的成员中查找,找不到就报错,不会去全局作用域匹配。
- 在成员函数外部(比如
无需显式定义!=的解决方法
有两种方式可以在成员函数内使用!=而不用显式定义:
- 方式一:改用
==取反的写法,绕开!=的直接调用:return !(*this == another); - 方式二:使用完整表达式写法,触发全局重载查找:
这种写法会让编译器同时查找成员和全局重载,从而匹配到全局的return *this != another;!=模板。
内容的提问来源于stack exchange,提问作者uni
相关产品推荐
相关产品推荐

