What is the C ++ syntax "A :: B: A {};" I mean

What is the meaning of C ++ syntax struct A::B:A {}; ? Where is the 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; } 
+54
c ++ syntax struct
Nov 29 '17 at 6:45
source share
2 answers

This definition

 struct A { struct B; }; 

Defines struct A with a declaration of a nested structure B 1 . The full name of B is A::B , you can say that B is inside the "namespace" of A Then this:

 struct A::B : A { // Note I added spaces }; 

Is the definition A::B , but the only one : indicates that it is derived from A

Now the interesting part is A::B::A::B Cut it up:

  • A::B stands for nested structure.
  • A::B::A accesses the name of the entered class A inside B Injection is related to inheritance.
  • A::B::A::B will again introduce the nested structure B into A

And you can continue ad-infinitum, or at least until your compiler fulfills its translation limit 2 .

Exciting intellectual exercise, but avoid like the plague in real code.




[class.qual] / 1 explains how the search works

If the qualified identifier nested name qualifier assigns a class, the name specified after defining the nested qualifier name in the class scope ([class.member.lookup]), except as listed below. The name should represent one or more members of this class or one of its base classes (section [class.derived]).

And the above text 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 name of the introduced class. For access verification, the name of the entered class is treated as if it were the public name of the member.

The above clearly says that when you run the full name with A:: you can specify a member or base class. Since A has no reason, you can only specify A::B ("member type"). But A::B also assigns a class. Therefore, we can specify the base or its part using A::B:: , which allows us to call A::B::A Now rinse and repeat.




<sub> 1 - Pay attention to this completely different B Not at all related to global struct B
2 - recommended minimum 256 in accordance with [implimits] /2.36

sub>

+111
Nov 29 '17 at 6:48
source share

First of all, struct B; is a direct declaration of struct B in the global namespace. This can be confusing, because in this example it really doesn't matter. This global B can be accessed as ::B or as soon as B

 struct A { struct B; }; 

It is a definition of struct A in the global namespace with direct declaration of the nested structure B (not the same as the previously declared B in the global namespace). This nested B can be accessed as ::A::B or A::B

 struct A::B:A { }; 

It is the definition of the nested structure B structure A , which is inherited from A (with no access specifier). It can be rewritten as follows:

 struct A::B : public A { }; 

Note that the definition of the definition of the nested structure B inside the definition of A like this will not work:

 struct A { struct B: A { // error: A is incomplete at this point }; }; 

And finally, A::B::A refers to the base class of the nested structure B , that is, to A , so A::B::A::B is simply equivalent to A::B

+20
Nov 29 '17 at 7:00
source share



All Articles