[class.member.lookup] (original) (raw)

11 Classes [class]

Name lookup can result in an ambiguity, in which case the program is ill-formed.

The following steps define the result of name lookup for a member namef in a class scope C.

The lookup set for f in C, called , consists of two component sets: the declaration set, a set of members named f; and the subobject set, a set of subobjects where declarations of these members (possibly includingusing-declarations) were found.

In the declaration set,using-declarations are replaced by the set of designated members that are not hidden or overridden by members of the derived class ([namespace.udecl]), and type declarations (including injected-class-names) are replaced by the types they designate.

is calculated as follows:

If C contains a declaration of the name f, the declaration set contains every declaration of f declared inC that satisfies the requirements of the language construct in which the lookup occurs.

[Note 1:

As another example, looking up a name in ausing-declaration ([namespace.udecl]) includes the declaration of a class or enumeration that would ordinarily be hidden by another declaration of that name in the same scope.

— _end note_]

If the resulting declaration set is not empty, the subobject set contains C itself, and calculation is complete.

Otherwise (i.e., C does not contain a declaration of for the resulting declaration set is empty), is initially empty.

If C has base classes, calculate the lookup set for f in each direct base class subobject , and merge each such lookup set in turn into .

The following steps define the result of merging lookup set into the intermediate :

The result of name lookup for f in C is the declaration set of .

If it is an invalid set, the program is ill-formed.

[Example 1: struct A { int x; }; struct B { float x; }; struct C: public A, public B { }; struct D: public virtual C { }; struct E: public virtual C { char x; }; struct F: public D, public E { }; int main() { F f; f.x = 0; }

is unambiguous because the A and B base class subobjects of D are also base class subobjects of E, so is discarded in the first merge step.

— _end example_]

If the name of an overloaded function is unambiguously found, overload resolution ([over.match]) also takes place before access control.

Ambiguities can often be resolved by qualifying a name with its class name.

[Example 2: struct A { int f();}; struct B { int f();}; struct C : A, B { int f() { return A::f() + B::f(); } }; — _end example_]

[Note 2:

A static member, a nested type or an enumerator defined in a base classT can unambiguously be found even if an object has more than one base class subobject of type T.

Two base class subobjects share the non-static member subobjects of their common virtual base classes.

— _end note_]

[Example 3: struct V { int v;};struct A { int a;static int s;enum { e };};struct B : A, virtual V { };struct C : A, virtual V { };struct D : B, C { };void f(D* pd) { pd->v++; pd->s++; int i = pd->e; pd->a++; } — _end example_]

[Note 3:

When virtual base classes are used, a hidden declaration can be reached along a path through the subobject lattice that does not pass through the hiding declaration.

This is not an ambiguity.

The identical use with non-virtual base classes is an ambiguity; in that case there is no unique instance of the name that hides all the others.

— _end note_]

[Example 4: struct V { int f(); int x; };struct W { int g(); int y; };struct B : virtual V, W { int f(); int x;int g(); int y;};struct C : virtual V, W { };struct D : B, C { void glorp(); };

virt W1 W V V W2 W B B B->W1 B->V C C C->V C->W2 D D D->B D->C

Figure 6: Name lookup [fig:class.lookup]

As illustrated in Figure 6, the names declared in V and the left-hand instance of Ware hidden by those in B, but the names declared in the right-hand instance of W are not hidden at all.

void D::glorp() { x++; f(); y++; g(); } — _end example_]

An explicit or implicit conversion from a pointer to or an expression designating an object of a derived class to a pointer or reference to one of its base classes shall unambiguously refer to a unique object representing the base class.

[Example 5: struct V { };struct A { };struct B : A, virtual V { };struct C : A, virtual V { };struct D : B, C { };void g() { D d; B* pb = &d; A* pa = &d; V* pv = &d; } — _end example_]

[Example 6: struct B1 { void f();static void f(int);int i;};struct B2 { void f(double);};struct I1: B1 { };struct I2: B1 { };struct D: I1, I2, B2 { using B1::f;using B2::f;void g() { f(); f(0); f(0.0); int B1::* mpB1 = &D::i; int D::* mpD = &D::i; } }; — _end example_]