dev*_*vsh 64 c++ syntax struct scope-resolution
C++语法struct 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;
}
Run Code Online (Sandbox Code Playgroud)
Sto*_*ica 119
这个定义
struct A {
struct B;
};
Run Code Online (Sandbox Code Playgroud)
A使用嵌套struct B1的声明定义结构.完全限定名称B是A::B,你可以说B是在"命名空间"里面A.然后这个:
struct A::B : A { // Note I added spaces
};
Run Code Online (Sandbox Code Playgroud)
是定义A::B,单个:指定它是从哪个派生而来的A.
现在,有趣的部分是A::B::A::B.让我们剖析一下:
A::B 命名嵌套结构.A::B::A访问A里面注入的类名B.注入是由于继承.A::B::A::B名嵌套结构B的A一次.并且您可以继续ad-infinitum,或者至少在您的编译器满足其转换限制2之前.
一个有趣的智力练习,但避免像实际代码中的瘟疫.
[class.qual]/1解释了查找的工作原理
如果嵌套名称说明符一的合格-ID提名一个类,则后指定的名称嵌套名称说明符在类([class.member.lookup])的范围抬头,除了例列出下面.该名称应代表该类或其基类之一的一个或多个成员(Clause [class.derived]).
上面的文本允许我们命名基类,因为[class]/2
的类名也被插入到类本身的范围; 这被称为注入类名.出于访问检查的目的,inject-class-name被视为公共成员名称.
以上清楚地说明,启动完全限定名称A::允许您指定成员或基类.由于A没有基础,您只能指定A::B("成员类型").但A::B也提名了一个班级.因此,我们可以指定一个基地或成员认为也有A::B::,这让我们的名字A::B::A.现在冲洗并重复.
1 - 注意它完全是另一个B.与全球无关struct B.
2 - 根据[implimits] /2.36建议的最小值256
use*_*670 21
首先struct B;是B全局命名空间中struct的前向声明.它可能令人困惑,因为它在这个例子中实际上并不相关.这个全局B可以作为::B或仅仅访问B.
struct A {
struct B;
};
Run Code Online (Sandbox Code Playgroud)
是A全局命名空间中struct的定义,带有嵌套 struct 的前向声明B(与先前B在全局命名空间中声明的不同).这个嵌套B可以作为::A::B或访问A::B.
struct A::B:A {
};
Run Code Online (Sandbox Code Playgroud)
是继承自B的struct 的嵌套结构的定义(省略了访问说明符).它可以改写为:AA
struct A::B
: public A
{
};
Run Code Online (Sandbox Code Playgroud)
请注意,B在这样的A定义中编写嵌套struct 的定义是行不通的:
struct A {
struct B: A { // error: A is incomplete at this point
};
};
Run Code Online (Sandbox Code Playgroud)
最后A::B::A是指嵌套struct的基类B,也就是说A,A::B::A::B等同于A::B.
| 归档时间: |
|
| 查看次数: |
8090 次 |
| 最近记录: |