From: Johannes Schaub (litb) on
Johannes Schaub (litb) wrote:

> 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):
>

By a literate interpretation of 10.2/2 in C++03, we could also go another
route. Notice that there is DR #39 which cites

"Each of these declarations that was introduced by a using-declaration is
considered to be from each sub-object of C that is of the type containing
the declaration designated by the using-declaration."

If we applied this to the lookup of "x" in "D", we would end up with "x" in
B->A, C->A and D: We would have found it in distinct subobjects and get an
ambiguity, at least this is what the DR says (using a similar example). I
don't understand how they come to that conclusion. There is wording
immediately preceeding the quoted text:

"A member name f in one sub-object B hides a member name f in a sub-object A
if A is a base class sub-object of B. Any declarations that are so hidden
are eliminated from consideration."

Since x in D hides C->A and B->A, we will not get an ambiguity, but end up
only finding the x in D. However, i fail to see the utility of considering
"x" to be of "A" for anything else than hiding base-class names relative to
the class where the using declaration appears in. I.e the "using A::x" would
hide C::x and D::x, but "D::x" should not hide "using A::x" - so we
shouldn't apply that rule, even tho a literate interpretation would force
that. In any case, without the literate and with the literate
interpretation, i can't see how compilation of the code would fail.

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