非限定名称查找查找内联命名空间成员

时间:2014-06-15 09:36:01

标签: c++ c++11 namespaces inline language-lawyer

我已经写了以下代码:

   #include <iostream>

    inline namespace M
    {
        int j=42;
    }

    int main(){ std::cout << j << "\n"; } //j is unqualified name here. 
                 //Hence, unqualified name lookup rules will be applied.
                 //This implies that member of inline namespace shall not be considered. 
                 //But it is not true

它工作正常。但我预计该计划的结构不合理。这是因为标准说(N3797,sec.7.3.1 / 7):

  

最后,通过显式查找封闭命名空间中的名称   资格(3.4.3.2)将包括内联命名空间的成员   即使有声明,也会被使用指令引入   该名称在封闭的命名空间中。

3.4.1 / 6节也没有说明在非限定名称查询中涉及内联命名空间的任何内容:

  

函数定义后使用的名称   declarator-id 28是命名空间N的成员(其中,仅用于   博览会的目的,N可以代表全球范围)   在使用它之前或在其中一个中使用之前声明   其封闭块(6.3)或应在其使用前声明   名称空间N或者,如果N是嵌套名称空间,则应在之前声明   它在N的封闭命名空间之一中使用。

这是一个g++错误,或者我理解规则不正确?

1 个答案:

答案 0 :(得分:4)

没有错误..

不,这不是g++(或clang++)中没有描述行为的错误,编译器应该找到j

inline namespace N {
  int j;
}

int main () {
  int a = j; // legal, `j` == `N::j`
}

标准说什么?

您缺少标准的一个非常重要的部分,即7.3.1§8,其中它声明内联命名空间的隐式的封闭命名空间具有< em> using指令引用内联命名空间。

  

[7.3.1]p8 命名空间定义 [namespace.def]

     
    

内联命名空间的成员可以在大多数方面使用,因为他们认为它们是封闭命名空间的成员。具体来说,内联命名空间及其封闭命名空间都被添加到参数依赖查找(3.4.2)中使用的关联命名空间集合中,只要其中一个是,并且 a using-directive (7.3.4)将内联命名空间的名称隐式插入到封闭命名空间中,与未命名的命名空间(7.3.1.1)一样。

  

精化

这意味着我们之前的示例在语义上等同于下面的内容,我们在其中引入了一个 using-directive 来将嵌套命名空间中的名称引入全局命名空间:

inline namespace N {
  int j;
}

using namespace N; // the implicit using-directive    

int main () {
  int a = j; // legal
}
相关问题