関連 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;
}
::S
はqualified-idです。
qualified-id::S::f
、S::
はネストされた名前指定子です。
非公式の言葉で1、nested-name-specifierはidの一部です
::
)idの先頭にある場合、および非常に非公式1、idはqualified-idまたはnqualified-idのいずれかです。 idがqualified-idの場合、実際には、ネストされた名前指定子とそれに続くnqualified-idの2つの部分で構成されます。
与えられた:
struct A {
struct B {
void F();
};
};
A
はnqualified-idです。::A
はqualified-idですが、-nested-name-specifierはありません。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]これはかなり不正確な説明です。文法を分かりやすい英語で説明するのは難しい...
ネストされた名前空間指定子は次のとおりです。
_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
_は構造体ではなく関数::S()
に解決されます(そのための優先規則は、質問の冒頭にリンクした質問のStackoverflowでここで説明されています)。ネストされた名前指定子ではありません。
良い質問!私はそれについて研究し実験することで何か新しいことを学びました。
あなたはコメントで正しいです、::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()はグローバル名前空間にあります(つまり、同じファイル、インクルードファイル、またはnamespace <name_of_namespace> { }
で囲まれていないコードの一部で宣言されています) 、new struct ::S
またはnew struct S
;のどちらでも使用できます。
私はこの質問に答えたいと思っていたので、これを学びました。より具体的で学んだ答えがある場合は、共有してください:)