4

ドラフト §7.3.1¶1 (n4527) では、名前空間定義の文法には以下が含まれます。

囲み名前空間指定子:

識別子

囲み名前空間指定子 :: 識別子

これにより、名前空間の定義が「::」で始まる識別子を持つことができなくなります

namespace d{ namespace e {} }
namespace ::d::e
{
void foo(){}
}

その制限には何か理由がありますか?


更新: 反対票といくつかの回答により、最初の文で「ドラフト」を意味するときに「標準」と書いたことに気づきました。私の弁護では、括弧内に文書番号を書きました。したがって、これは C++1z のネストされた名前空間定義機能に関する質問であることを強調しておきます。

4

2 に答える 2

0

以下の 2 つの使用A::法は大きく異なります。

void f();
namespace A {
  void f();
  namespace B {
    void f();
    void g() {
      A::f();      // #1
      ::f();
    }
  }
}
namespace A::N {}  // #2
namespace /*::*/N {}
  1. これにより、名前空間が選択B::fされ、非修飾ルックアップによる検出が回避されます。この使用例はグローバル名前空間にも適用されるため、::f;.
  2. これにより、名前空間が確立されます (つまり、作成または再開されます)。この使用例は明らかにグローバル名前空間には適用されないため::N、最後の行で許可する理由はありません。
于 2017-09-18T05:27:28.977 に答える
0

で始まる行は::、グローバル名前空間を使用することをコンパイラに示します。例えば:

void foo()
{
  std::cout << "1" << std::endl;
}

namespace d
{
  void foo()
  {
    std::cout << "2" << std::endl;
  }

  void example()
  {
    foo();
    ::foo();
  }
}

このコードは次のように出力されます。

2
1

最初の呼び出しはに行きd::foo()、2 番目の呼び出しはfoo()グローバル名前空間に行きます。その::ため、名前空間の先頭に a をd配置すると、名前空間を作成しようとしているときに、グローバル名前空間に配置しているように見えますが、これはまったく意味がありません。

于 2015-11-10T15:15:09.400 に答える