You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

结构体成员函数无法使用默认不等运算符的原因及解决方法

关于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未定义”错误;但在成员函数外部使用!=运算符却可正常运行。

问题

出现该现象的原因是什么?是否可以无需显式定义不等运算符,就能在成员函数内使用它?


原因分析

  1. 默认生成规则的差异:

    • 当默认定义<=>运算符时,编译器会自动生成成员版的operator==,所以成员函数里直接调用operator==(another)能找到这个成员函数,编译正常。
    • 但operator!=不会生成成员版,而是依赖全局重载模板实现——这个模板通过!(a == b)完成不等判断。不过该全局模板优先级低于成员函数,在成员函数内部写operator != (another)时,编译器会优先查找类的成员函数,找不到就直接报错,不会匹配全局模板。
  2. 查找规则的内外差异:

    • 在成员函数外部(比如main中)写pt1 != pt2,编译器会同时查找成员和全局作用域的重载,能匹配到全局的!=模板,因此正常编译。
    • 但在成员函数内部,operator != (another)等价于this->operator!=(another),属于隐式成员函数调用,编译器只会在当前类的成员中查找,找不到就报错,不会去全局作用域匹配。

无需显式定义!=的解决方法

有两种方式可以在成员函数内使用!=而不用显式定义:

  • 方式一:改用==取反的写法,绕开!=的直接调用:
    return !(*this == another);
    
  • 方式二:使用完整表达式写法,触发全局重载查找:
    return *this != another;
    
    这种写法会让编译器同时查找成员和全局重载,从而匹配到全局的!=模板。

内容的提问来源于stack exchange,提问作者uni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 07:15:04