Member lookup rules are defined in Section 10.2/2
The following steps define the result of name lookup in a class scope,
C
. First, every declaration for the name in the class and in each of its base class sub-objects is considered. A member namef
in one sub-objectB
hides a member namef
in a sub-objectA
ifA
is a base class sub-object ofB
. Any declarations that are so hidden are eliminated from consideration. Each of these declarations that was introduced by a using-declaration is considered to be from each sub-object ofC
that is of the type containing the declara-tion designated by the using-declaration. If the resulting set of declarations are not all from sub-objects of the same type, or the set has a nonstatic member and includes members from distinct sub-objects, there is an ambiguity and the program is ill-formed. Otherwise that set is the result of the lookup.
class A {
public:
int f(int);
};
class B {
public:
int f();
};
class C : public A, public B {};
int main()
{
C c;
c.f(); // ambiguous
}
So you can use the using
declarations A::f
and B::f
to resolve that ambiguity
class C : public A, public B {
using A::f;
using B::f;
};
int main()
{
C c;
c.f(); // fine
}
The second code works flawlessly because void foo(float)
is inside C’s scope. Actually d.foo(5);
calls void foo(float)
and not the int
version.