What does C++ syntax struct A::B:A {};
mean? Where is this name definition (or access) described in the C++ standard?
#include <iostream>
struct B;
struct A {
struct B;
};
struct A::B:A {
};
int main() {
A::B::A::B b;
std::cout<<"Sizeof A::B::A::B is " << sizeof(A::B::A::B)<<std::endl;
return 0;
}
First of all
struct B;
is a forward declaration of structB
in global namespace. It might be confusing because it is actually not relevant in this example. This globalB
can be accessed as::B
or as justB
.Is a definition of struct
A
in global namespace with a forward declaration of nested structB
(not the same as previously declaredB
in global namespace). This nestedB
can be accessed as::A::B
orA::B
.Is a definition of nested struct
B
of structA
that inherits fromA
(with access specifier omitted). It can be rewritten to:Note that writing definition of nested struct
B
inside ofA
definition like this won't work:And finally
A::B::A
is referring to the base class of nested structB
, that is toA
, soA::B::A::B
is equivalent to justA::B
.This definition
Defines a struct
A
with a declaration of a nested structB
1. The fully qualified name ofB
isA::B
, you could sayB
is inside the "namespace" ofA
. Then this:Is the definition of
A::B
, and the single:
specifies that it is derived fromA
.Now, the interesting part is
A::B::A::B
. Let's dissect it:A::B
names the nested structure.A::B::A
accesses the injected class nameA
insideB
. The injection is due to the inheritance.A::B::A::B
names the nested structureB
inA
again.And you can continue ad-infinitum, or at least until your compiler meets its translation limit2.
A fun intellectual exercise, but avoid like the plague in actual code.
[class.qual]/1 explains how the lookup works
And the text above allows us to name the base class because [class]/2
The above clearly says that starting a fully qualified name with
A::
allows you to specify a member or a base class. SinceA
has no bases, you can only specifyA::B
(a "member type"). ButA::B
also nominates a class. So we may specify a base or member of that as well withA::B::
, which allows us to nameA::B::A
. Now rinse and repeat.1 - Note it's a completely other
B
. Not at all related to the globalstruct B
.2 - A recommended minimum of 256 according to [implimits]/2.36