【问题标题】:which are the rewritten candidates for != operator这是 != 运算符的重写候选者
【发布时间】:2020-12-10 02:40:05
【问题描述】:

标准中的相关规则说:
over.match.oper#3.4.3

改写后的候选集确定如下:

  1. 对于关系 ([expr.rel]) 运算符,重写的候选包括表达式 x y 的所有未重写的候选。
  2. 对于关系 ([expr.rel]) 和三向比较 ([expr.spaceship]) 运算符,重写的候选还包括一个合成候选,两个参数的顺序颠倒,对于每个未重写表达式 y x.
  3. 的候选者
  4. 对于 != 运算符 ([expr.eq]),重写的候选项包括表达式 x == y 的所有未重写的候选项
  5. 对于等式运算符,重写的候选还包括一个合成候选,两个参数的顺序颠倒,用于表达式 y == x 的每个未重写候选。
  6. 对于所有其他运算符,重写的候选集为空。

考虑以下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!=yx==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 看看这个pagenon-rewritten字样的解释和我的差不多。但是,它仍然无法解释if @ is != and the selected candidate is a synthesized candidate with reversed order of parameters, !(y == x),

标签: c++ language-lawyer c++20


【解决方案1】:

我怀疑这是[over.match.oper]/3.4.4授予的:

对于等式运算符,对于表达式 y 的每个未重写的候选者,重写的候选者还包括一个 综合 候选者,两个参数的顺序颠倒了== x。

等式运算符是两者 operator==operator!=。另请注意“综合”与“重写”不是同义词:四组候选是成员候选非成员候选内置候选 em> 和 重写的候选者。一个合成的候选只属于这些集合中的一个(在这种情况下是重写的候选集)。

因此,我的理解是x != y 的重写候选包括两者

  • x == y 的所有未重写候选对象,以及
  • y == x 的非重写候选合成候选。

所以y == x 的合成候选也是重写的候选。然后[over.match.oper]/9.1 开始:

如果@!= 并且选择的候选是参数顺序相反的合成候选,!(y == x)

也就是说,如果选择的重写候选是上面合成的y == x的候选,那么结果就是!(y == x)

【讨论】:

  • 谢谢。考虑第 4 条,这是否意味着候选包括“表达式 y == x 的每个未重写候选”和每个前者的合成候选,还是只包括每个前者的合成候选?
  • @jack X 在算法上,我相信它更像是:“考虑表达式y == x。为该表达式收集所有候选C,不包括重写的候选集。对于每个候选cC 中,合成一个新的候选f,参数颠倒。然后将每个候选f 添加到x @ y 的重写候选集中。"
  • 我看到了一个绝妙的解释。那么用于确定哪个最好的参数列表是 (x, y) 而不是 (y, x),对吧?
  • @jackX 是的,没错。 (参数列表 x, y 用于从 所有 候选记忆中进行选择,而不仅仅是重写的候选 - /9 仅在所选候选恰好在重写候选集中时使用。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-25
  • 1970-01-01
  • 2016-10-29
相关资源
最近更新 更多