题
$ 10.2/4-“ [注意:在详细型式特定符(3.4.4)或基本指定器(第10条)中查找名称,例如,忽略所有非型声明,同时查找嵌套的名称 - 名称 - 特定符(3.4.3)忽略了功能,变量和枚举声明。”
在描述有关名称查找的同时,我发现此部分在本节中非常令人困惑。
void S(){}
struct S{
S(){cout << 1;}
void f(){}
static const int x = 0;
};
int main(){
struct S *p = new struct ::S; // here ::S refers to type
p->::S::f();
S::x; // base specifier, ignores the function declaration 'S'
::S(); // nested name specifier, ignores the struct declaration 'S'.
delete p;
}
我的问题:
我对规则的理解是否正确?
为什么
::S
在生产线上自动进行新处理以表示结构S
, ,而在最后一行::S
表示功能S
在全球名称空间中。这是否表明文档中的歧义,还是我远离C ++标准文档的另一天?
解决方案
问题1:我认为是这样。
Q2:与C的兼容性 struct
在C中,标签名称就是一个标签名称。为了能够以独立的方式使用它,您需要一个 typedef
. 。在C ++中,您不需要Typedef,这使Live更轻松。但是,C ++规则已经使已经现有的C标头导入将标签名称“超载”具有函数名称“超载”的标题变得复杂。规范的例子是Unix stat()
使用一个功能 struct stat*
作为参数。
Q3:标准阅读通常很困难...您需要已经知道其他地方没有任何地方修改您正在阅读的内容。人们知道如何做是语言律师...并不奇怪...
其他提示
您对第二条评论有误解。在 S::x
, , 这 S
是嵌套名称指定符中的名称。标准用“基本分配器”所指的是以下
namespace B { struct X { }; void X() }
struct A : B::X { }; // B::X is a base-specifier
您也对此不正确:
::S();
//嵌套的名称说明符,忽略struct声明's'。
该代码调用功能不是因为 ::S
将是一个嵌套名称的指示符(它不是嵌套名称指示符!),但是由于功能名称隐藏类或枚举名称,如果函数和类/枚举都在同一范围中声明。
fwiw,以下代码对您的主第2行同样有效
p->S::f();
重要的是 S
preceedes a ::
, ,这使查找忽略该功能。你放了 ::
前 S
在您的情况下没有影响。