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です。

modified-id ::S::fでは、nested-name-specifierS::です。

非公式の用語1では、nested-name-specifierIDの一部です。

  • 修飾 IDの最初か、最初のスコープ解決演算子 ( ::) がIDの最初と
  • は、 qualified-idの最後のスコープ解決演算子で終わります。

非常に非公式に1idは、qualified-idまたはunqualified- id のいずれかです。idqualified-idの場合、実際には、ネストされた名前指定子とそれに続くunqualified-idの 2 つの部分で構成されます。

与えられた:

struct  A {
    struct B {
        void F();
    };
};
  • Aunqualified-idです。
  • ::A修飾 IDですが、ネストされた名前指定子がありません。
  • A::B修飾 IDA::あり、ネストされた名前指定子です。
  • ::A::B修飾 IDA::あり、ネストされた名前指定子です。
  • A::B::F修飾 IDであり、B::A::B::ネストされた名前指定子です。
  • ::A::B::F修飾 IDであり、B::A::B::ネストされた名前指定子です。

[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

その中で、nested-name-specifier は絶対的ではないかもしれません (::グローバル スコープを参照するために が前に付けられます) ::

あなたの例では、 struct ではなく::Sfunction に解決され::S()ます(その優先順位ルールは、質問の最初にリンクした質問の Stackoverflow でここで説明されています)。したがって、ネストされた名前指定子ではありません。

于 2010-11-05T06:27:58.357 に答える
4

良い質問!私はそれについて研究し、実験することで何か新しいことを学びました。

あなたはあなたのコメントに正しいです、::S(); //Is ::S a nested name specifier <-- Yes, Indeed!

名前空間の作成を開始すると、それが理解できるようになります。変数は名前空間全体で同じ名前を持つことができ、::演算子はそれらを区別するものです。名前空間は、ある意味ではクラスのようなものであり、抽象化のもう 1 つのレイヤーです。名前空間で退屈させたくありません。この例のネストされた名前指定子を理解できないかもしれません...これを考慮してください:

#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() はグローバル名前空間にあるため (つまり、同じファイルまたはインクルード ファイルまたは によってエンベロープされていないコードの一部で宣言されているため、 or ;namespace <name_of_namespace> { }を使用できます。new struct ::Snew struct S

この質問に答えたいと思っていたので、これを学んだので、より具体的で学んだ答えがあれば、共有してください:)

于 2010-11-05T06:46:18.207 に答える