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)
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)
};