6

次の名前空間定義は、最初の宣言がコメント アウトされているとコンパイルに失敗します。の最初の宣言fooがコメント解除されている場合、問題なくコンパイルされます。

namespace Y
{
    //void foo();
    void ::Y::foo(){}
}

標準の関連部分 (§8.3¶1) は次のように述べています。

declarator-id が修飾されている場合、宣言は以前に宣言されたメンバーを参照するものとします

この規則により、他の名前空間への名前の導入が防止されることを理解しています。そのルールを緩和して、現在の名前空間を参照する修飾された idを許可できるかどうか疑問に思います。

4

1 に答える 1

3

CWG #482が該当します:

8.3 [dcl.meaning] パラグラフ 1 によると、[…]
この制限は、次のような例を禁止します。

void f();
void ::f();        // error: qualified declarator

namespace N {
  void f();
  void N::f() { }  // error: qualified declarator
}

そのような宣言を禁止する正当な理由はないようであり、多くの実装では、標準で禁止されているにもかかわらず、宣言を受け入れています。それらを許可するように規格を変更する必要がありますか?

2006 年 4 月の会議のメモ:

問題 548について議論する中で、CWG は、名前空間内の修飾された宣言子の禁止を削除する必要があることに同意しました。

したがって、最初の宣言fooが存在する場合、コードは有効です(2012年頃の時点で、GCCにはオープンバグレポートがあります)。ただし、そうでない場合でも、引用された文言は引き続き適用され、修飾された宣言が不適切な形式になります。その場合を認める理由はありません。修飾名ルックアップはそれが参照するものを決定する必要があるため、名前がすでに宣言されていることを直感的に意味します。

于 2015-11-11T08:49:39.217 に答える