Re: ambiguous method calling
On Dec 19, 12:11 pm, "Daniel Kr?gler" <daniel.krueg...@googlemail.com>
wrote:
On 19 Dez., 07:46, Thiago Souto Maior Cordeiro de Farias
<ts...@cin.ufpe.br> wrote:
Ambiguous? the type is given in the calling function, but the
compiler needs the scope for the correct base where the
desired method relies.
The call is ambigous, because base class function
overloads are not *implicitly* added to the overload
set of the derived class (This is an encapsulation
feature of C++).
If found by member name lookup, the member functions of a base class
are added to the overload set of a derived class:
#include <iostream>
struct A
{
void f(double d);
void f(int i);
};
struct B : public A
{
};
int main()
{
B b;
b.f(3); // OK: calls A::f(int)
}
The error in the original example has nothing to do with overload
resolution. After all, even if there is only one member function named
"f" that could possibly be called - the call to f() can nonetheless
still be ambiguous:
struct A
{
short f;
};
struct B
{
int f;
};
struct C
{
void f()
{
}
};
struct D : public A,
public B,
public C
{
};
int main()
{
D d;
d.f(); // Error - f is ambiguous
}
The ambiguity error in the example above occurs before overload
resolution of the f() function call; the error actually occurs during
member name lookup, that is, when the compiler is looking up the
member name "f" inside D. Essentially, a member name is considered
ambiguous if - during its lookup - the compiler finds the name defined
in two different base classes - and neither of the two classes is a
subclass of the other.
Just add the following three using declarations:
using A::f;
using B::f;
using C::f;
which will ensure the all base class overloads
are added to the overload set considered in D::a.
More precisely, the "using" declarations are effectively treated as
member name declarations inside the class in which they appear (at
least for the purposes of member name lookup). And since a name
declared in a derived class "hides" the same name declared in a base
class, a "using" declaration effectively prevents the compiler from
finding "f" in any of D's base classes. So, by effectively "moving"
the base class declarations of "f" into D, the compiler finds "f"
defined only in "D", meaning that the call to the f() member function
call is no longer ambiguous.
Greg
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]