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; }
:: is the scope resolution operator - used to qualify names.
Arithmetic OperatorsAdds two operands. A + B = 30. − Subtracts second operand from the first.
"%s%d%s%d\n" is the format string; it tells the printf function how to format and display the output. Anything in the format string that doesn't have a % immediately in front of it is displayed as is. %s and %d are conversion specifiers; they tell printf how to interpret the remaining arguments.
C++ Arithmetic Operators a + b; Here, the + operator is used to add two variables a and b . Similarly there are various other arithmetic operators in C++. Operator. Operation.
This definition
struct A { struct B; };
Defines a struct A
with a declaration of a nested struct B
1. The fully qualified name of B
is A::B
, you could say B
is inside the "namespace" of A
. Then this:
struct A::B : A { // Note I added spaces };
Is the definition of A::B
, and the single :
specifies that it is derived from A
.
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 name A
inside B
. The injection is due to the inheritance.A::B::A::B
names the nested structure B
in A
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
If the nested-name-specifier of a qualified-id nominates a class, the name specified after the nested-name-specifier is looked up in the scope of the class ([class.member.lookup]), except for the cases listed below. The name shall represent one or more members of that class or of one of its base classes (Clause [class.derived]).
And the text above allows us to name the base class because [class]/2
The class-name is also inserted into the scope of the class itself; this is known as the injected-class-name. For purposes of access checking, the injected-class-name is treated as if it were a public member name.
The above clearly says that starting a fully qualified name with A::
allows you to specify a member or a base class. Since A
has no bases, you can only specify A::B
(a "member type"). But A::B
also nominates a class. So we may specify a base or member of that as well with A::B::
, which allows us to name A::B::A
. Now rinse and repeat.
1 - Note it's a completely other B
. Not at all related to the global struct B
.
2 - A recommended minimum of 256 according to [implimits]/2.36
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With