Title
Overriding virtual functions, also with explicit object parameters
Status
review
Section
11.7.3 [class.virtual]
Submitter
Jens Maurer

Created on 2021-12-10.00:00:00 last changed 18 months ago

Messages

Date: 2023-06-15.09:34:54

Proposed resolution:

  1. Change in 11.7.3 [class.virtual] paragraph 2 as follows:

    If a virtual member function F is declared in a class B, and, in a class D derived (directly or indirectly) from B, a declaration of a member function G corresponds (6.4.1 [basic.scope.scope]) to a declaration of F as if declared in D (12.2.2.1 [over.match.funcs.general]), ignoring trailing requires-clauses, and, if G is an explicit object member function, ignoring object parameters, and, if G is an implicit object member function, F and G have the same ref-qualifier (or absence thereof), then G overrides [ Footnote: ... ] F .
  2. Remove 11.7.3 [class.virtual] paragraph 7 as follows:

    The ref-qualifier , or lack thereof, of an overriding function shall be the same as that of the overridden function.
Date: 2021-12-10.00:00:00

Consider:

  struct B {
    virtual void f();   // #1
  };

  struct D : B {
    void f();           // #2
  };

Subclause 11.7.3 [class.virtual] paragraph 2 says:

If a virtual member function F is declared in a class B, and, in a class D derived (directly or indirectly) from B, a declaration of a member function G corresponds (6.4.1 [basic.scope.scope]) to a declaration of F, ignoring trailing requires-clauses, then G overrides [ Footnote: ... ] F .

Subclause 6.4.1 [basic.scope.scope] paragraph 4 defines "corresponds" as follows:

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 non-object-parameter-type-list, equivalent (13.7.7.2 [temp.over.link]) trailing requires-clauses (if any, except as specified in 13.7.5 [temp.friend]), and, if both are non-static members, they have corresponding object parameters, or
    • both declare function templates with...

Subclause 6.4.1 [basic.scope.scope] paragraph 3 defines "corresponding object parameters" as follows:

Two non-static member functions have corresponding object parameters if:
  • exactly one is an implicit object member function with no ref-qualifier and the types of their object parameters (9.3.4.6 [dcl.fct]), after removing top-level references, are the same, or
  • their object parameters have the same type.

In the example, B::f has an object parameter of type B, but D::f has an object parameter of type D. Thus, the two functions do not correspond, and thus D::f does not override B::f. That is an unintended alteration of the status quo ante.

See also issue 2553.

History
Date User Action Args
2023-06-15 09:34:54adminsetstatus: open -> review
2022-03-24 07:15:00adminsetmessages: + msg6772
2021-12-10 00:00:00admincreate