在查找名称空间名称时可以考虑哪些其他名称,而不是命名空间名称?

时间:2014-09-26 11:55:23

标签: c++ c++11 namespaces language-lawyer name-lookup

§3.4.6/ 1:

  

using-directive namespace-alias-definition 中,   查找名称空间名称或查找名称    nested-name-specifier 仅考虑名称空间名称。

基本上,我要问的是:“为什么这个段落是必要的?”

2 个答案:

答案 0 :(得分:2)

Defect report 373: Lookup on namespace qualified name in using-directive举例说明了措辞的重要性:

namespace X {
  namespace Y {
    struct X {
      void f()
      {
        using namespace X::Y;
        namespace Z = X::Y;
      }
    };
  }
}

X结构或命名空间中引用了哪个using namespace X::Y?如果3.4.6中没有这样的措辞,那将是模棱两可的。

这实际上导致了措辞的改变:

  

在using-directive或namespace-alias-definition中查找namespace-name时,只考虑名称空间名称。

我们今天所拥有的,因为原始措辞没有涵盖嵌套名称说明符

歧义是使用嵌套名称说明符,如果我们查看5.1.1部分nested-name-specifier: ::opt type-name :: ::opt namespace-name :: decltype-specifier :: nested-name-specifier identifier :: nested-name-specifier templateopt simple-template-id :: 一般中的draft C++11 standard语法,则为如下:

7.3.1

以及我不会复制的以下段落,因为它们很大,不会将嵌套名称说明符限制为名称空间

据我所知,{{1}} 命名空间定义足以限制 namespace-name 以防止出现歧义。

答案 1 :(得分:1)

Clang对namespace usingalias directives的单元测试正是您问题的答案:

  

clang-cc -fsyntax-only -verify%s

struct ns1 {}; // This is not a namespace, although a namespace has ns1 as a name
void ns2();
int ns3 = 0;

namespace ns0 {
  namespace ns1 {
    struct test0 {};
  }
  namespace ns2 {
    struct test1 {};
  }
  namespace ns3 {
    struct test2 {};
  }
}

using namespace ns0;

namespace test3 = ns1; // don't get confused
namespace test4 = ns2;
namespace test5 = ns3;

using namespace ns1; // don't get confused
using namespace ns2;
using namespace ns3;

test0 a;
test1 b;
test2 c;

此问题也在n3160 defect report

中讨论过