我已经写了以下代码:
#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++
错误,或者我理解规则不正确?
答案 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
}