首页 > 解决方案 > P1787 中关于一组非静态成员函数是否可以重载的替代规则

问题描述

阅读P1787后,我对这个示例中的评论感到困惑。那是:

struct X {
  static void f();
  void f() const;  // error: redeclaration
  void g();
  void g() const;  // OK
  void g() &;      // error: redeclaration
};

显然,如果按照当前标准中的over.load,它们是无效的重载声明。但是,该子条款已在 P1787 中删除。
根据 P1787 中所说,我可以理解 name 的第二个声明之后的注释f,因为第一个声明和第二个声明是对应的,并且它们声明了同一个实体,但是它们违反了以下规则:

对于一个实体的任意两个声明

如果一个人将其声明为变量或函数,则另一个人应将其声明为同一类型之一。

坦率地说,我无法理解 name 的最后声明之后的评论g。IIUC,这三个名称声明g不对应。由于以下规则:

如果两个声明(重新)引入相同的名称、都声明构造函数或都声明析构函数,则两个声明对应,除非:

  • [...]
  • each 声明一个函数或函数模板,除非
  • 两者都使用相同的参数类型列表声明函数[脚注:隐式对象参数([over.match.funcs])不是参数类型列表的一部分。— 结束脚注],等效 ([temp.over.link]) 尾随要求子句(如果有,除非 [temp.friend] 中指定),并且,如果两者都是非静态成员,相同的 cv 限定符 (如果有)和 ref-qualifier(如果两者都有)

尽管它们具有相同的参数类型列表,但它们都是非静态成员,并且没有相同的cv-qualifiers 和 ref-qualifier,因此它们不是对应的声明。g我在 P1787 中找不到任何说明此类声明格式错误的规则,那么如何解释该评论?

标签: c++overloadinglanguage-lawyerclass-members

解决方案


ref-qualifier 只需要相同"(if both have one)"

如果只有一个声明具有引用限定符而另一个没有,则该措辞暗示这两个声明对应,假设所有其他条件都得到满足。

在提供的示例中,这意味着void g() &;重新声明void g();.


推荐阅读