Topic: does qualifying a method name select a receiver subobject?
Author: "Scott McPeak" <smcpeak@cs.berkeley.edu>
Date: Sun, 19 Feb 2006 19:23:05 CST Raw View
I've found the answer, in 10.1/4:
In such lattices, explicit qualification can be used to specify which
subobject is meant.
This text is inside "example" brackets, so is technically not
normative,
but I think that's just a typographic oversight.
Also, FWIW, the example code can be simplified to just make 'foo' a
nonstatic data member, and 'bar' attempt to return B::foo.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: "Scott McPeak" <smcpeak@cs.berkeley.edu>
Date: Wed, 15 Feb 2006 12:53:36 CST Raw View
Consider this code:
struct A {
void foo();
};
struct B : A {
};
struct C : A, B { // A A
void bar(); // | |
}; // | B
// |/
void C::bar() // C
{
(*this).B::foo();
}
My question is whether the call to foo is ambiguous.
Clearly, had the call been "A::foo()", it would be ambiguous because
there are two subobjects of type A [10.2/2].
Also clearly, the *intent* of the code is to invoke foo while passing
the A subobject contained in the B subobject, rather than the one
directly contained in the C subobject. That is, providing a qualifier
for the name foo is intended to also select a receiver subobject.
However, I cannot find any justification for allowing this code (and
its obvious intended semantics) in the standard.
-- My analysis of the standard's interpretation of the call to foo. --
1. The expression "(*this)" is an lvalue of type "C" [9.3.2/1,
5.3.1/1].
2. The name "B" looks up to the class B [3.4.5/4].
3. The name "foo" is looked up in class B [3.4.3.1/1], which
unambiguously finds "A::foo" [10.2/2], which is not overloaded.
4. The "this" parameter of the callee is initialized as if by direct
an explicit type conversion of the pointer to the object of the call
[5.2.2/4], where "object of the call" means the object denoted by
"(*this)". Thus, the source pointer has type "C*".
5. The type of the "this" parameter of A::foo is A* [9.3.2/1].
6. The explicit type conversion from "C*" to "A*" would be equivalent
to a static_cast [5.4/5], which in turn is equivalent to a cast-free
initialization [5.2.9/2], which in turn would use standard conversions
[8.5/14, last bullet], of which the pointer conversion from derived to
base class is the relevant one, but requires that the conversion be
unambiguous [4.10/3], but it is not [10.2/7].
Hence the call is ill-formed.
-- Further discussion --
The crucial steps above are of course 3 and 5, which conclude that the
"this" parameter of the callee has type A*. The code's intent is that
is has type B* because it was found by looking in B. But I can find
nothing that would connect the lookup procedure for foo to its type
once found.
Moreover, it is *not* the case that inheritance "copies" all the base
class members into the derived class [13.2/1], so we can't just
pretend that there is a copy of A::foo called B::foo in B.
However, 10/1 says in part:
Unless redefined in the derived class, members of a base class are
also considered to be members of the derived class.
What does this actually mean? When, exactly, are they "considered"
members of the derived class? 10.2/2 is pretty clear about treating
base class members differently from derived class members.
Furthermore, 9.3.2/4 gives rules for matching the cv-qualification of
the object of the call and the "this" parameter; yet the analysis
above suggests this is redundant, since 9.3.2/1 specifies how "this"
acquires the cv-qualifiers of the method, and (as above) the rules for
standard convertibility imply everything in 9.3.2/4. So either
9.3.2/4 is redundant, or something is wrong with my analysis.
-Scott
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]