From: Jia-sen on
It is normal that a function in derived class hides one in a base
class. But, I could explain to myself how a base function could hide
one in a derived class. Here is an example:

struct A { int x(); };
struct B : A { };
struct C : A { };
struct D : B, C {
using A::x;
int x(double);

void f();
};

void D::f() {
x(1.0); //error in gcc v4.4.0, No match for
'A::x(double)'
}

int main() { }

Isn't there a D::x(double)? I would appreciate if someone could
explain the error message.

Thanks,
Jason

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Daniel Krügler on
On 12 Aug., 15:07, Jia-sen <baowei2...(a)gmail.com> wrote:
> It is normal that a function in derived class hides one in a base
> class. But, I could explain to myself how a base function could hide
> one in a derived class. Here is an example:
>
> struct A { int x(); };
> struct B : A { };
> struct C : A { };
> struct D : B, C {
> using A::x;
> int x(double);
>
> void f();
>
> };
>
> void D::f() {
> x(1.0); //error in gcc v4.4.0, No match for
> 'A::x(double)'
>
> }
>
> int main() { }
>
> Isn't there a D::x(double)? I would appreciate if someone could
> explain the error message.

Poor compiler-diagnostic, I guess. There *is*
D::x(double), but the primary problem is, that the
using-declaration is ambiguous, because there are
two possible A::x: One via base class B, and one
via base class C.

You should either omit the using-declaration from
D or you should pick either B::x or C::x via such
a using-declaration.

HTH & Greetings from Bremen,

Daniel Kr�gler


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Bo Persson on
Jia-sen wrote:
> It is normal that a function in derived class hides one in a base
> class. But, I could explain to myself how a base function could
> hide one in a derived class. Here is an example:
>
> struct A { int x(); };
> struct B : A { };
> struct C : A { };
> struct D : B, C {
> using A::x;
> int x(double);
>
> void f();
> };
>
> void D::f() {
> x(1.0); //error in gcc v4.4.0, No match for
> 'A::x(double)'
> }
>
> int main() { }
>
> Isn't there a D::x(double)? I would appreciate if someone could
> explain the error message.
>

The compiler could be confused because there are actually two A::x
functions, one in B and one in C.

Another compiler complains about that:

Comeau C/C++ 4.3.3 (Oct 25 2003 12:02:26) for MS_WINDOWS_x86
Copyright 1988-2003 Comeau Computing. All rights reserved.
MODE:strict errors C++

"X:\reference\quick_test.cpp", line 5: error: "A::x" is ambiguous
using A::x;
^

Bo Persson


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Jeremy on
>
> Isn't there a D::x(double)? I would appreciate if someone could
> explain the error message.
>
> Thanks,
> Jason

You explicitly say 'using A::x', also you only declared D::x(double),
you did not define it so you would get an undefined reference after
removing the 'using' keyword.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Johannes Schaub (litb) on
Jia-sen wrote:

> It is normal that a function in derived class hides one in a base
> class. But, I could explain to myself how a base function could hide
> one in a derived class. Here is an example:
>
> struct A { int x(); };
> struct B : A { };
> struct C : A { };
> struct D : B, C {
> using A::x;
> int x(double);
>
> void f();
> };
>
> void D::f() {
> x(1.0); //error in gcc v4.4.0, No match for
> 'A::x(double)'
> }
>
> int main() { }
>
> Isn't there a D::x(double)? I would appreciate if someone could
> explain the error message.
>

I believe that there is nothing wrong with this code and it's a GCC bug.
Clang also compiles this fine. The using declaration overloads the function-
declaration in D. And "x(1.0)" will select "x(double)" of D. It would error
out if you would call "x();" only. Notice that the using declaration itself
is fine, because "A::x" refers to the member x of A, which is not in an
ambiguous subobject of A. Only when selected, the rules added by N1626 to
5.2.5p4 make it ambiguous (i believe the behavior was not specified by
C++03):

"If E2 is a non-static data member or a non-static member function, the
program is ill-formed if the class of which E2 is directly a member is an
ambiguous base (10.2) of the naming class (11.2) of E2."

(the naming class is D, and the class which x is directly a member of is A).
Notice that the new name-lookup introduced by that paper for C++0x changes
some behavior that is nowadays ill-formed, which might be interesting in
this context:

struct A { int x(); };
struct B : A { };
struct C : A { };
struct E : B, C { };
struct D : E {
using E::x;
int x(double);

void f();
};

This using-declaration is ill-formed currently, because "E::x" will find x
in two distinct subobjects and inherently cause an ambiguous lookup result.
The more logical behavior of C++0x makes this fine aswell, because the
lookup will resolve E::x to A's declaration of x. Only once called, the
result is an ambiguity by 5.2.5p4.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]