以::开头的C ++嵌套命名空间定义

时间:2015-11-10 15:05:58

标签: c++ namespaces language-lawyer c++17

在草案§7.3.1¶1(n4527)中,命名空间定义的语法包含:

  

包围名称空间说明符:

     
    

标识符

         

enclosing-namespace-specifier :: identifier

  

这可以防止名称空间定义具有以“::”

开头的标识符
namespace d{ namespace e {} }
namespace ::d::e
{
void foo(){}
}

这种限制有什么理由吗?

更新 downvote(s)和一些答案使我意识到当我在第一句话中表示“草稿”时我写了“标准”。在我的辩护中,我确实在括号中写了文档编号。因此,让我强调这是关于C ++ 1z的嵌套命名空间定义功能的问题。

2 个答案:

答案 0 :(得分: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(),第二个调用转到全局命名空间中的foo()。因此,将::放在命名空间的开头会使你看起来正在将d放在全局命名空间中,当你试图为它创建一个命名空间时,它实际上并不是没有任何意义。

答案 1 :(得分:0)

以下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