重载解析重写表达式
我们详细说明在重写调用的支持下,使用比较运算符对表达式求值。
调用相等运算符进行编译:
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 天,点击查看活动详情”