c++overloadinglanguage-lawyerclass-members

The alternative rule in P1787 for whether a set of non-static member functions can be overloaded


After reading P1787, I have a confusion about the comment in this example. That is:

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

Obviously, they're invalid overload declarations if per over.load in the current standard. however, the subclause has been removed in P1787.
According to what says in P1787, I can understand the comment after the second declaration for name f, because the first declaration and the second declaration are corresponding and they declared the same entity, however, they violate the following rule:

For any two declarations of an entity

If one declares it to be a variable or function, the other shall declare it as one of the same type.

Frankly, I can't understand the comments after the last declaration for the name g. IIUC, these three declarations for name g do not correspond. Because of the following rule:

Two declarations correspond if they (re)introduce the same name, both declare constructors, or both declare destructors, unless:

  • [...]
  • each declares a function or function template, except when
  • both declare functions with the same parameter-type-list[Footnote: An implicit object parameter ([over.match.funcs]) is not part of the parameter-type-list. — end footnote], equivalent ([temp.over.link]) trailing requires-clauses (if any, except as specified in [temp.friend]), and, if both are non-static members, the same cv-qualifiers (if any) and ref-qualifier (if both have one)

Although they have the same parameter-type-list, they're all non-static members and do not have the same cv-qualifiers and ref-qualifier, hence they're not corresponding declarations. I can't find any rule that says such declarations for g are ill-formed in P1787, so how to interpret the comment?


Solution

  • The ref-qualifier only needs to be the same "(if both have one)".

    If only one declaration has a ref-qualifier and the other doesn't, the wording implies that the two declarations correspond, assuming all other conditions are satisfied.

    In the provided example, that means void g() &; is a redeclaration of void g();.