struct A { int x; }; // S(x,A) = { { A::x }, { A } }
struct B { float x; }; // S(x,B) = { { B::x }, { B } }
struct C: public A, public B { }; // S(x,C) = { invalid, { A in C, B in C } }
struct D: public virtual C { }; // S(x,D) = S(x,C)
struct E: public virtual C { char x; }; // S(x,E) = { { E::x }, { E } }
struct F: public D, public E { }; // S(x,F) = S(x,E)
int main() {
F f;
f.x = 0; // OK, lookup finds E::x
}
struct A {
int f();
};
struct B {
int f();
};
struct C : A, B {
int f() { return A::f() + B::f(); }
}; — end example
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++; // OK: only one v (virtual)
pd->s++; // OK: only one s (static)
int i = pd->e; // OK: only one e (enumerator)
pd->a++; // error, ambiguous: two as in D
} — end example
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(); };
void D::glorp() {
x++; // OK: B::x hides V::x
f(); // OK: B::f() hides V::f()
y++; // error: B::y and C's W::y
g(); // error: B::g() and C's W::g()
} — end example
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; // error, ambiguous: C's A or B's A?
V* pv = &d; // OK: only one V subobject
} — end example
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(); // Ambiguous conversion of this
f(0); // Unambiguous (static)
f(0.0); // Unambiguous (only one B2)
int B1::* mpB1 = &D::i; // Unambiguous
int D::* mpD = &D::i; // Ambiguous conversion
}
}; — end example