What does C++ syntax struct A::B:A {};
mean? Where is this name definition (or access) described in the C++ standard?
c++语法结构A:::B:A {};的意思吗?c++标准中描述的名称定义(或访问)在哪里?
#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;
}
2 个解决方案
#1
116
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:
使用嵌套结构B1的声明定义结构a。B的全限定名是A::B,可以说B在A的“名称空间”内,然后是:
struct A::B : A { // Note I added spaces
};
Is the definition of A::B
, and the single :
specifies that it is derived from A
.
是A::B的定义,单数:指定它是从A衍生而来的。
Now, the interesting part is A::B::A::B
. Let's dissect it:
现在,有趣的部分是。让我们仔细分析它:
-
A::B
names the nested structure. - A::B命名嵌套结构。
-
A::B::A
accesses the injected class nameA
insideB
. The injection is due to the inheritance. - A:::A访问注入的类名B中的A。注入是由于继承。
-
A::B::A::B
names the nested structureB
inA
again. - B: A: A: B在A中重新命名了嵌套结构B。
And you can continue ad-infinitum, or at least until your compiler meets its translation limit2.
你可以无限地继续,或者至少直到你的编译器满足它的翻译限制2。
A fun intellectual exercise, but avoid like the plague in actual code.
这是一个有趣的智力练习,但要避免像实际代码中的瘟疫。
[class.qual]/1 explains how the lookup works
(类。1解释查找是如何工作的
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]).
如果限定id的nested-name说明符指定了一个类,则在类的范围([class.member.lookup])中查找nested-name说明符之后指定的名称,但下面列出的情况除外。该名称应表示该类或其基类之一的一个或多个成员(子句[class.派生])。
And the text above allows us to name the base class because [class]/2
上面的文本允许我们命名基类,因为[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.
上面明确指出,使用::开始一个完全限定名可以指定成员或基类。由于A没有基数,所以只能指定A::B(“成员类型”)。但是A: B也提名一个班。因此,我们也可以用a:::B:::来指定基地或成员,这样我们就可以命名a::::: a。现在清洗和重复。
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
1 -注意这是一个完全不同的b,与全局结构完全无关。2 -根据[implimit]/2.36,建议最小256
#2
21
First of all struct B;
is a forward declaration of struct B
in global namespace. It might be confusing because it is actually not relevant in this example. This global B
can be accessed as ::B
or as just B
.
首先是结构B;是全局命名空间中的struct B的正向声明。它可能会令人困惑,因为在这个例子中它实际上并不相关。本全球B可被访问为:B或仅为B。
struct A {
struct B;
};
Is a definition of struct A
in global namespace with a forward declaration of nested struct B
(not the same as previously declared B
in global namespace). This nested B
can be accessed as ::A::B
or A::B
.
是全局名称空间中的struct a的定义,带有嵌套struct B的正向声明(与全局名称空间中先前声明的B不同)。这个嵌套B可以被访问为::A::B或A::B。
struct A::B:A {
};
Is a definition of nested struct B
of struct A
that inherits from A
(with access specifier omitted). It can be rewritten to:
是继承自a的结构体的嵌套结构体B的定义(省略了访问说明符)。可以改写为:
struct A::B
: public A
{
};
Note that writing definition of nested struct B
inside of A
definition like this won't work:
注意,在这样的定义中编写嵌套结构体B的定义是行不通的:
struct A {
struct B: A { // error: A is incomplete at this point
};
};
And finally A::B::A
is referring to the base class of nested struct B
, that is to A
, so A::B::A::B
is equivalent to just A::B
.
最后A:::B::A是指嵌套结构体B的基类,即A的基类,所以A:::B::A::B就等于A::B。
#1
116
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:
使用嵌套结构B1的声明定义结构a。B的全限定名是A::B,可以说B在A的“名称空间”内,然后是:
struct A::B : A { // Note I added spaces
};
Is the definition of A::B
, and the single :
specifies that it is derived from A
.
是A::B的定义,单数:指定它是从A衍生而来的。
Now, the interesting part is A::B::A::B
. Let's dissect it:
现在,有趣的部分是。让我们仔细分析它:
-
A::B
names the nested structure. - A::B命名嵌套结构。
-
A::B::A
accesses the injected class nameA
insideB
. The injection is due to the inheritance. - A:::A访问注入的类名B中的A。注入是由于继承。
-
A::B::A::B
names the nested structureB
inA
again. - B: A: A: B在A中重新命名了嵌套结构B。
And you can continue ad-infinitum, or at least until your compiler meets its translation limit2.
你可以无限地继续,或者至少直到你的编译器满足它的翻译限制2。
A fun intellectual exercise, but avoid like the plague in actual code.
这是一个有趣的智力练习,但要避免像实际代码中的瘟疫。
[class.qual]/1 explains how the lookup works
(类。1解释查找是如何工作的
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]).
如果限定id的nested-name说明符指定了一个类,则在类的范围([class.member.lookup])中查找nested-name说明符之后指定的名称,但下面列出的情况除外。该名称应表示该类或其基类之一的一个或多个成员(子句[class.派生])。
And the text above allows us to name the base class because [class]/2
上面的文本允许我们命名基类,因为[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.
上面明确指出,使用::开始一个完全限定名可以指定成员或基类。由于A没有基数,所以只能指定A::B(“成员类型”)。但是A: B也提名一个班。因此,我们也可以用a:::B:::来指定基地或成员,这样我们就可以命名a::::: a。现在清洗和重复。
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
1 -注意这是一个完全不同的b,与全局结构完全无关。2 -根据[implimit]/2.36,建议最小256
#2
21
First of all struct B;
is a forward declaration of struct B
in global namespace. It might be confusing because it is actually not relevant in this example. This global B
can be accessed as ::B
or as just B
.
首先是结构B;是全局命名空间中的struct B的正向声明。它可能会令人困惑,因为在这个例子中它实际上并不相关。本全球B可被访问为:B或仅为B。
struct A {
struct B;
};
Is a definition of struct A
in global namespace with a forward declaration of nested struct B
(not the same as previously declared B
in global namespace). This nested B
can be accessed as ::A::B
or A::B
.
是全局名称空间中的struct a的定义,带有嵌套struct B的正向声明(与全局名称空间中先前声明的B不同)。这个嵌套B可以被访问为::A::B或A::B。
struct A::B:A {
};
Is a definition of nested struct B
of struct A
that inherits from A
(with access specifier omitted). It can be rewritten to:
是继承自a的结构体的嵌套结构体B的定义(省略了访问说明符)。可以改写为:
struct A::B
: public A
{
};
Note that writing definition of nested struct B
inside of A
definition like this won't work:
注意,在这样的定义中编写嵌套结构体B的定义是行不通的:
struct A {
struct B: A { // error: A is incomplete at this point
};
};
And finally A::B::A
is referring to the base class of nested struct B
, that is to A
, so A::B::A::B
is equivalent to just A::B
.
最后A:::B::A是指嵌套结构体B的基类,即A的基类,所以A:::B::A::B就等于A::B。