$ 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;
}
我的问题:
我对规则的理解是否正确?
为什么行上的::S
自动处理表示结构S
,而在最后一行::S
表示全局命名空间中的函数S
。
这是否意味着文档中存在歧义,或者是否又是我远离C ++标准文档的另一天?
答案 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
对您的案例没有任何影响。