重载解析重写表达式

313 阅读2分钟

重载解析重写表达式

我们详细说明在重写调用的支持下,使用比较运算符对表达式求值。

调用相等运算符进行编译:

x !=y

编译器现在可能会尝试以下所有操作

x.operator!=(y)

//调用成员运算符!= x

operator!=(x,y)

// 挑选一个独立的操作员!= x和y

!x.operator==(y)

//x的剔除成员运算符==

!operator==(x, y)

//为x和y调用独立的运算符==

!x.operator==(y)

//剔除成员operator==由operator<=>为x生成

!y.operator==(x)

//调用y的operator<=>生成的成员operator==

最后一种形式尝试支持第一个操作数的隐式类型转换,这要求操作数是形参。

通常,编译器会尝试调用:

一个独立的操作符!=:operator!=(x,y)

或一个成员操作符!=:x.operator!=(y)定义了两个操作符!=是一个歧义错误。

独立运算符==:!x.operator==(y)注意,成员operator==可能由默认的operator<=>成员生成。

同样,定义了两个操作符==是一个歧义错误。如果由于默认操作符<=>而生成了成员操作符==,这也适用。

当需要对第一个操作数v进行隐式类型转换时,编译器还会尝试重新排序操作数。

v!=y  // V转换为y的类型

在这种情况下,编译器尝试调用:

  • 一个独立的运算符!=:运算符!=(v, y)
  • 独立运算符==:!operator==(v, y)
  • 一个成员操作符==:!y.o over ==(v)

(注意,成员操作符==可能由默认的操作符<=>成员生成)

因此,在这种情况下,独立函数比成员函数更受欢迎,因为操作数的顺序不必改变。

请注意,重写的表达式永远不会尝试调用成员操作符!=

调用关系运算符

对于关系操作符,我们有类似的行为,除了重写的语句返回到新的操作符<=>并将结果与0进行比较。该运算符的行为类似于一个三向比较函数,为小于返回负值,为等于返回0,为greuter返回正值(它不返回数值,而是返回类似的值)。

例如,编译:

x<=y

编译器现在可能会尝试以下所有操作:

x.operator<=(y)

//为x调用成员操作符<=

operator<=(x,y)

//为x和y挑选一个独立的操作符<=

  
x.operator<=>(y)<=0

//为x调用成员运算符<=>

operator<=>(x,y)<=0

//为x和y调用独立运算符<=>

  
0 <= y.operator<=>(x)

//y的剔除成员运算符<=>

同样,最后一种形式尝试支持第一个操作数的隐式类型转换,因为它必须成为一个形参。


开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 N 天,点击查看活动详情