9

重複の可能性:
冗長なスコープ修飾がコンパイラでサポートされているのはなぜですか? また、それは合法ですか?

これがコンパイルされるとは思いませんが、コンパイルされます。これはコンパイラのバグでしょうか、それとも正しい意味を持っているのでしょうか?

$ g++ -c scopes.cpp
$ cat scopes.cpp
class Log {
public:
    Log() { }
    static void fn() { }
};

void test() {
    Log::Log::Log::Log::Log::Log::fn();
}

$ g++ --version
g++ (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3
4

1 に答える 1

9

はい、合法です。クラスの名前は、独自の名前空間に挿入されます。これは、injected-class-nameと呼ばれます。C++03 §9/2 から:

[...]クラス名もクラス自体のスコープに挿入されます。これは、注入されたクラス名として知られています。アクセス チェックの目的で、injected-class-nameはパブリック メンバー名であるかのように扱われます。

Log::Log特定のコンテキストでのみ許可されるクラス コンストラクターに名前を付けるLog::Log::...ことに注意してLogくださいfn。具体的には、§3.4.3.1/1a は次のように述べています。

ネストされた名前指定子がクラスを指名し、ネストCされた名前指定子の後に指定された名前が、で検索されたときに、(節 9)の注入されたクラス名である場合、その名前は代わりにコンストラクターに名前を付けると見なされます。クラスの。このようなコンストラクター名は、クラス定義の外に現れるコンストラクター定義のdeclarator-idでのみ使用されます。CCC

于 2012-10-11T16:14:15.387 に答える