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

C++编译器如何匹配Class::operator==?C++20相等运算符行为疑问

C20与C17中operator==匹配规则差异及代码问题解析

你的猜测是否正确?

你的猜测方向是对的,但更准确的表述是:C++20为相等类运算符(==、!=)引入了对称查找机制,当直接匹配a == b失败时,编译器会自动尝试交换操作数顺序,匹配b == a,这就是代码在C++20下能正常编译的核心原因。

代码编译差异的具体原因

C++17编译失败的原因

在C++17及更早标准中,执行a == b(A& == B&)时,编译器的查找逻辑是:

  1. 首先查找A的成员operator==,它的参数是A&。由于B是私有继承A,在main函数这类外部作用域中,B到A的类型转换是不可访问的,无法将B&隐式转换为A&来匹配这个运算符。
  2. C++17不会自动尝试交换操作数顺序,因此没有机会匹配B的operator==(A&),最终因找不到合法的运算符而报错。

C++20编译成功的原因

C++20对==和!=运算符新增了对称查找规则:
当原顺序的运算符匹配失败后,编译器会自动生成交换操作数后的表达式(即把a == b转为b == a),再重新进行查找。
对于你的代码,b == a会直接匹配B的成员operator==(A&)——b是B&类型,a是A&类型,完全符合参数要求,因此可以正常调用,编译通过。

C++中operator==的匹配规则

C++20之前的规则

对于表达式x == y,编译器会按以下顺序查找:

  • 成员运算符查找:优先查找x的类型中定义的成员operator==,要求参数能匹配y的类型(或通过隐式转换匹配)。
  • 非成员运算符查找:如果成员查找失败,在全局命名空间以及x、y类型所在的命名空间中,查找非成员operator==,要求参数能匹配(x, y)的类型组合。
  • 不会自动交换操作数顺序,必须手动写y == x才能触发对y的运算符查找。

C++20的规则(新增对称查找)

C++20仅对==和!=运算符扩展了查找逻辑:

  1. 先执行C++20之前的常规查找(成员+非成员)。
  2. 如果常规查找失败,且运算符是==或!=,则交换操作数顺序,生成y == x,再重新执行一次常规查找。
  3. 若交换后的查找成功,则使用该运算符;若仍失败,才会编译报错。

注意:该对称查找仅适用于相等类运算符,+、-、>等其他运算符不支持自动交换查找。

代码中各表达式的匹配情况

  • a == a:直接匹配A::operator==(A&),正常执行。
  • a == b(C++20):原顺序匹配失败,交换为b == a,匹配B::operator==(A&)。
  • b == a:直接匹配B::operator==(A&),正常执行。
  • b == b:直接匹配B::operator==(B&),正常执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 11:37:10