名称查找澄清

时间:2010-11-04 06:01:24

标签: c++ c++11 name-lookup

  

$ 10.2 / 4-“[注意:在...中查找名称   详细说明类型(3.4.4)   或基本说明符(第10条),for   实例,忽略所有非类型   声明,同时查找名称   在嵌套名称说明符(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 ++标准文档的另一天?

2 个答案:

答案 0 :(得分:1)

Q1:我想是的。

Q2:与C的兼容性当您在C中声明struct时,标签名称就是标签名称。为了能够以独立方式使用它,您需要typedef。在C ++中,您不需要typedef,这使得实时更容易。但是,由于需要能够导入已经使用函数名称“重载”标记名称的现有C头,因此C ++规则变得复杂。这个规范的例子是Unix stat()函数,它使用struct stat*作为参数。

第三季度:标准阅读通常很难......你需要知道其他地方没有地方修改你正在阅读的内容。知道怎么做的人是语言律师并不奇怪......

答案 1 :(得分:0)

你错了第二条评论。在S::x中,S是嵌套名称说明符中的名称。标准所引用的“base-specifier”是以下

namespace B { struct X { }; void X() }
struct A : B::X { }; // B::X is a base-specifier

你对此也不正确:

  

::S(); //嵌套名称说明符,忽略结构声明'S'。

该代码调用该函数不是因为::S将是嵌套名称说明符(它不是嵌套名称说明符!),而是因为函数名称隐藏了类或枚举名称并且类/枚举在同一范围内声明。

FWIW,以下代码对主

的第2行同样有效
p->S::f();

重要的是S先于::,这使查找忽略了该函数。您在{/ em> ::之前放置S 对您的案例没有任何影响。