One can call a base class function from a derived class function with the same name. But I can't find a quote from the Standard supporting this

Viewed 63

Consider the following snippet:

struct Base{
   void f() {}
};

struct Derived: public Base{
   void f() { Base::f(); }
};

Derived d;
int main(){
    d.f();
}

The snippet works fine. i.e., d.f() calls Base::f(). But I can't find a quote from the standard supporting this.

1 Answers

All standard references below refer to N4659: March 2017 post-Kona working draft/C++17 DIS.


This is [class.qual]/1 [extract, emphasis mine]:

If the nested-name-specifier of a qualified-id nominates a class, the name specified after the nested-name-specifier is looked up in the scope of the class [...]

In your example, Base:: is the nested-name-specifier, and the name specified after it is f(), for which lookup is thus performed in the scope of the class Base. This rule will not be affected by shadowing on the call site, as we are using a qualified name, and we may note that if we remove f() from Base the qualified id will (as expected for qualified lookup) not search for f() of the scope of the derived class.

struct Base {};

struct Derived: public Base {
   void f() { 
       Base::f();  // error: 'f' is not a member of 'Base
   }
};

We may also note that [class.qual]/3 particularly mentions this case:

A class member name hidden by a name in a nested declarative region or by the name of a derived class member can still be found if qualified by the name of its class followed by the ​::​ operator.

but as pointed out in a comment by @LanguageLawyer, this paragraph should arguably be non-normative(1).


(1) [class.qual]/3 gives a specific example of how [class.qual]/1 can apply / the effect of it. However, these kind of segments in the standard are typically non-normative (examples, notes, and so on), whereas [class.qual]/3, which brings no ”new normative" value (already covered in [class.qual]/1), is not wrapped as a note or an example.

Related