根据c ++标准,以下程序是否格式正确或格式不正确?
namespace N { int i; }
using namespace N;
using ::i;
int main() {}
我使用不同的编译器得到不同的结果:
根据c ++标准,该程序是否格式正确或格式不正确?需要参考c ++标准。
我试图找出应该提交错误的编译器。
答案 0 :(得分:5)
良好的。
using-directive 不会在全局命名空间中引入名称i
,但会在查找期间使用它。 using-declaration 使用限定查找来查找i
;在[3.4.3.2 p1,p2]中指定了存在 using-directives 的限定查找(引自N4527,当前工作草案):
如果 qualified-id 的嵌套名称说明符指定名称空间 (包括嵌套名称说明符为
::
的情况,即 提名全局命名空间),后面指定的名称 在命名空间的范围内查找 nested-name-specifier 。 [...]对于名称空间
X
和名称m
,名称空间限定的查找集 S(X,m)定义如下:设 S'(X,m)是所有的集合m
中X
的声明和X
的内联命名空间集(7.3.1)。如果 S'(X,m)不为空, S(X,m)是 S'(X,m);否则, S(X,m)就是 所有名称空间的 S(N i ,m)联合 N i 被提名 通过X
中的 using-directives 及其内联命名空间集。
因此,对于限定查找,第一步是查找直接在嵌套名称说明符(i
所指示的命名空间中生成的::
声明这个案例)。没有这样的声明,因此查找然后进入第二步,即形成由 using-directives 指定的所有名称空间中的限定查找找到的i
的所有声明的集合。全局命名空间。该集由N::i
组成,这是名称查找的结果,并通过using声明在全局名称空间中作为名称引入。
我觉得值得注意的是(尽管很明显)这种限定查找的定义是递归的:在引号中使用符号,在每个命名空间中使用限定查找 N i 将首先查找直接在 N i 中生成的声明,然后,如果找不到声明,则将继续查找由 using-directives <指定的名称空间/ em> in N i ,依此类推。
对于它的价值,MSVC也接受这些代码。
答案 1 :(得分:4)
N::i
; §3.4.3.2/ 2&amp; / 3:
对于名称空间
X
和名称m
,名称空间限定的查找集S(X, m)
的定义如下:让S'(X, m)
成为所有的集合m
中X
的声明以及X
的内联命名空间集 (7.3.1)。如果S'(X, m)
不为空,则S(X, m)
为S'(X, m)
; 否则,S(X, m)
是所有名称空间的S(N
i, m)
的并集N
iX
中的using-directives 及其内联命名空间集。
给定X::m
(其中X
是用户声明的命名空间),或给定::m
(其中X
是全局命名空间),如果S(X, m)
只有一个成员,或者如果{。}} 引用的上下文是using-declaration(7.3.3),S(X, m)
是 所需的m
声明集。
程序中只有一个由using-directive指定的命名空间:N
。因此它包含在联盟中,::i
已解析为N::i
。
请注意,GCC与其查找不一致:在另一个上下文中使用::i
很好。
namespace N { int i; }
using namespace N;
int main() {
::i = 5;
}
这compiles。上述引用中显示了使用声明作为上下文的唯一区别,并不影响既定结论。