31

此相关

我想知道嵌套名称说明符到底是什么?我查了草稿,但我可以理解语法,因为我还没有参加任何编译器设计课程。

void S(){}

struct S{
   S(){cout << 1;}
   void f(){}
   static const int x = 0;
}; 

int main(){ 
   struct S *p = new struct ::S;  
   p->::S::f();

   S::x;  

   ::S(); // Is ::S a nested name specifier?
   delete p;
} 
4

3 回答 3

39

::S是一个合格的 id

qualified-id ::S::f中,S::是一个nested-name-specifier

在非正式术语1中,嵌套名称说明符id的一部分

  • 如果一个出现在id的最开始,或者在初始范围解析运算符 ( )之后开始,并且::
  • qualified-id中的最后一个范围解析运算符结束。

非常非正式地1,一个id是一个合格的 id或一个不合格的 id。如果idqualified-id,它实际上由两部分组成:一个嵌套名称说明符,后跟一个unqualified-id

鉴于:

struct  A {
    struct B {
        void F();
    };
};
  • A是一个不合格的 id
  • ::A是一个qualified-id但没有nested-name-specifier
  • A::B是一个限定 ID并且A::是一个嵌套名称说明符
  • ::A::B是一个限定 ID并且A::是一个嵌套名称说明符
  • A::B::F是一个qualified-idB::,两者A::B::都是nested-name-specifiers
  • ::A::B::F是一个qualified-idB::,两者A::B::都是nested-name-specifiers

[1] 这是一个相当不准确的描述。用简单的英语很难描述语法...

于 2010-11-05T05:29:57.183 回答
8

嵌套命名空间说明符是:

nested-name-specifier :
    class-or-namespace-name::nested-name-specifier(optional)

也就是说,命名空间和类名的非空列表,每个后跟 ::,表示程序的整个“命名空间树”中的相对分支。例如,my_namespace::my_namespace::inner_namespace::my_namespace::my_class::my_class::

请特别注意与以下内容的区别:

qualified-namespace-specifier :
    ::(optional) nested-name-specifier(optional) class-or-namespace-name

嵌套名称说明符可能不是绝对的(前缀::为表示全局范围),而限定名称空间说明符可以是,但不以 . 结尾::

在您的示例中,::S解析为 function ::S(),而不是 struct (在您在问题开始时链接到的问题中的 Stackoverflow 上讨论了其优先规则),因此它不是嵌套名称说明符。

于 2010-11-05T06:27:58.357 回答
4

好问题!我学到了一些新的研究和实验。

你的评论是对的,::S(); //Is ::S a nested name specifier <-- Yes, Indeed!

当您开始创建命名空间时,您会喜欢上它。变量可以在命名空间中具有相同的名称,并且::操作符是它们的区别。命名空间在某种意义上就像类,是另一层抽象。我不想让你厌烦命名空间。您可能不喜欢此示例中的嵌套名称说明符......考虑这个:

#include <iostream>
using namespace std;

int count(0);                   // Used for iteration

class outer {
public:
    static int count;           // counts the number of outer classes
    class inner {
    public:
        static int count;       // counts the number of inner classes
    };
};

int outer::count(42);            // assume there are 42 outer classes
int outer::inner::count(32768);  // assume there are 2^15 inner classes
                                 // getting the hang of it?

int main() {
    // how do we access these numbers?
    //
    // using "count = ?" is quite ambiguous since we don't explicitly know which
    // count we are referring to.
    //
    // Nested name specifiers help us out here

    cout << ::count << endl;        // The iterator value
    cout << outer::count << endl;           // the number of outer classes instantiated
    cout << outer::inner::count << endl;    // the number of inner classes instantiated
    return 0;
}

请注意,我::count在本来可以简单使用的地方使用了count. ::count指全局命名空间。

因此,在您的情况下,由于 S() 位于全局名称空间中(即,它在同一文件或包含的文件或未被 包裹的任何代码段中声明namespace <name_of_namespace> { },您可以使用new struct ::Sor new struct S; 无论您喜欢哪个。

我刚刚了解到这一点,因为我很想回答这个问题,所以如果您有更具体和学过的答案,请分享:)

于 2010-11-05T06:46:18.207 回答