什么是嵌套名称说明符?

时间:2010-11-05 05:19:31

标签: c++ names

this

相关

我想知道嵌套名称说明符究竟是什么?我在草稿中查了一下但是我能理解语法,因为我还没有学过任何编译器设计课程。

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

3 个答案:

答案 0 :(得分:34)

::S qualified-id

qualified-id ::S::f中,S::嵌套名称说明符

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

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

非正式 1 id qualified-id unqualified-id 。如果 id qualified-id ,它实际上由两部分组成:嵌套名称说明符后跟 unqualified-id

假设:

struct  A {
    struct B {
        void F();
    };
};
  • A unqualified-id
  • ::A qualified-id ,但没有嵌套名称说明符
  • A::B qualified-id A::嵌套名称说明符
  • ::A::B qualified-id A::嵌套名称说明符
  • A::B::F qualified-id B::A::B::都是嵌套名称说明符
  • ::A::B::F qualified-id B::A::B::都是嵌套名称说明符

[1]这是一个非常不精确的描述。用简单的英语来描述语法很难......

答案 1 :(得分:6)

嵌套的命名空间说明符是:

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

因为嵌套名称说明符可能不是绝对的(前缀为::以引用全局作用域),而qualified-namespace-specifier可以是,但不以{{1结尾}}

在您的示例中,::解析为函数::S,而不是结构(在您在问题开头链接到的问题中,Stackoverflow上讨论了这种结构的优先级规则),所以它不是嵌套的名称说明符。

答案 2 :(得分:3)

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

您的评论正确,::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> { }包围的任何代码片段,你可以使用{{ 1}}或new struct ::S;无论您喜欢哪种。

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