【发布时间】:2020-12-10 02:40:05
【问题描述】:
标准中的相关规则说:
over.match.oper#3.4.3
改写后的候选集确定如下:
- 对于关系 ([expr.rel]) 运算符,重写的候选包括表达式 x y 的所有未重写的候选。
- 对于关系 ([expr.rel]) 和三向比较 ([expr.spaceship]) 运算符,重写的候选还包括一个合成候选,两个参数的顺序颠倒,对于每个未重写表达式 y x.
的候选者- 对于 != 运算符 ([expr.eq]),重写的候选项包括表达式 x == y 的所有未重写的候选项。
- 对于等式运算符,重写的候选还包括一个合成候选,两个参数的顺序颠倒,用于表达式 y == x 的每个未重写候选。
- 对于所有其他运算符,重写的候选集为空。
考虑以下code:
#include <iostream>
struct Data{
bool operator ==(int c){
return true;
}
};
int main(){
Data d;
bool r = 0 != d; // should be ill-formed
}
我不知道为什么代码可以被编译器编译。 IMO,表达式 0!=d 的重写候选应包括表达式 x == y 的所有未重写的候选。我对non-rewritten Candidates 的理解是,考虑除表达式 x==y 的重写候选者之外的任何候选者,用于操作 x != y。毕竟,项目符号 4 用于形成一个重写的候选集。因此,第四个项目符号不应该继续适用于已重写为原始表达式x!=y 的x==y。在我的示例中,0!=d 的重写候选集仅包含 0==d 的候选集,不应考虑 d==0 的任何重写候选集;
page 中关于 non-rewritten 措辞的相关规则与我的解释类似。 (不包括改写的候选人)
对于 != 运算符 ([expr.eq]),重写的候选者包括表达式 x == y 的所有成员、非成员和内置候选者。
不过,继续看下一段,即:
如果通过重载决议为运算符@选择了重写的运算符==候选,则其返回类型应为cv bool,x@y解释为:
- 如果 @ 是 != 并且所选候选者是参数顺序相反的合成候选者,!(y == x),
既然!=的重写候选不能继续重写,那它怎么会有一个参数顺序颠倒的综合候选呢?我不知道为什么。如何解读!=的重写候选规则,尤其是non-rewritten Candidate和最后一条规则?
【问题讨论】:
-
鉴于规则 3 和 4 以及一些常识,我们可以很容易地发现这两个规则都可以应用。因此非重写本质上适用于用户代码。
-
@cigien 我忘了加
c++。 -
@Phil1970 我不明白你的意思。 IMO,包括所有未重写的候选者意味着考虑除表达式
x==y的重写候选者之外的任何候选者,用于操作x != y。毕竟,子弹 4 是用来形成一个重写的候选集 -
@Phil1970 看看这个page,non-rewritten字样的解释和我的差不多。但是,它仍然无法解释
if @ is != and the selected candidate is a synthesized candidate with reversed order of parameters, !(y == x),
标签: c++ language-lawyer c++20