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

C++23中类的比较运算符能否拥有非类类型的显式对象参数?

C++23中类的比较运算符能否使用与类类型不同的显式对象参数?

先看示例代码:

struct A {
    int i;
    constexpr bool operator==(this int x, int y) { return x == y; }
    constexpr operator int() const { return i; }
};

我们结合两种比较场景的编译器行为,对照C++23标准分析合规性:

一、不等比较场景

测试代码:

static_assert( A{0} != A{1} );

编译器行为:

  • GCC、Clang可正常编译
  • MSVC报错:
error C2803: 'operator ==' must have at least one formal parameter of class type
error C2333: 'A::operator ==': error in function declaration; skipping function body

二、相等比较场景

测试代码:

static_assert( A{2} == A{2} );

编译器行为:

  • 仅GCC可正常编译
  • Clang报错:
error: use of overloaded operator '==' is ambiguous (with operand types 'A' and 'A')
   11 | static_assert( A{2} == A{2} );
note: candidate function
    3 |     constexpr bool operator==(this int x, int y) { return x == y; }
note: built-in candidate operator==(int, int)

标准符合性分析

  1. 运算符声明的合法性
    根据C++23标准[dcl.fct.def.this]条款规定:类成员函数的显式对象参数类型必须是该类的cv限定版本、引用或指针(即cv A、cv A&、cv A&&或cv A*),不能是int这类与类无关的类型。

因此示例中operator==的声明本身是非法的,MSVC拒绝编译该函数是正确的(尽管错误信息沿用了旧标准的表述);而GCC和Clang允许该声明,不符合C++23标准。

  1. 相等比较的歧义问题
    即便忽略声明的合法性,Clang的报错也符合标准:当调用A{2} == A{2}时,存在两个可行的候选函数:
  • 自定义的operator==(int, int)(通过显式对象参数绑定左操作数的隐式转换结果,右操作数也转换为int)
  • 内置的operator==(int, int)(两个A对象都隐式转换为int后调用)

这两个候选函数签名完全一致,编译器无法区分,因此产生歧义。GCC未检测到该歧义,不符合标准。

内容的提问来源于Stack Exchange,提问作者Fedor

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 03:00:03