1

In the below Example,

void f(double, double);  // at global scope

struct Grandparent {
    void f(int);
    void f(double, double);
};

struct Parent : public Grandparent {
    void f(int);  // hides all overloads of Grandparent::f
};

struct Child : public Parent {
    void g() { f(2.14, 3.17); }  // resolves to Parent::f
};

How the declaration of Parent::f dominates and hides all of the more-ancestral declarations regardless of signature, that is, Parent::f(int) dominates and hides the declaration of Grandparent::f(double, double) even though the two member functions have very different signatures?

I came across this example via https://en.wikipedia.org/wiki/Dominance_(C%2B%2B)

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
Sripooja
  • 49
  • 1
  • 9
  • Wow, never heard of the term "dominance". Is that an "official"/accepted term? – Rakete1111 May 23 '18 at 05:53
  • Even I am surprised by seeing this term :-O.Came across this,when I was trying to know in-depth about Function Overloading. – Sripooja May 23 '18 at 05:56
  • 1
    @Rakete1111: I don't think so. Overload resolution / name lookup is described in the C++ standards without reference to "Dominance". For me that Wikipedia page is a particularly poor one. – Bathsheba May 23 '18 at 06:35
  • 2
    The normal term for this is "shadowing" or "name hiding" – M.M May 23 '18 at 06:39

1 Answers1

4

Becasue what is hidden is name; signature isn't involved. According to the rule of name lookup,

name lookup examines the scopes as described below, until it finds at least one declaration of any kind, at which time the lookup stops and no further scopes are examined.

For this case, when the name f is found at the scope of Parent then name lookup stops; the names in Grandparent won't be considered at all. (BTW: After name lookup, in overload resolution signature will be checked to select the best match one)

If it's not the behavior you expected, you can introduce names via using.

struct Parent : public Grandparent {
    using Grandparent::f;
    void f(int);
};

struct Child : public Parent {
    void g() { f(2.14, 3.17); }  // refer to Grandparent::f(double, double)
};
songyuanyao
  • 169,198
  • 16
  • 310
  • 405