$ 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;
} 

我的问题:

  1. 我对规则的理解是否正确?

  2. 为什么 ::S 在生产线上自动进行新处理以表示结构 S, ,而在最后一行 ::S 表示功能 S 在全球名称空间中。

  3. 这是否表明文档中的歧义,还是我远离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 在您的情况下没有影响。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top