通过using-directive在using声明中查找名称

时间:2015-07-25 16:49:18

标签: c++ language-lawyer using-directives name-lookup using-declaration

根据c ++标准,以下程序是否格式正确或格式不正确?

namespace N { int i; }
using namespace N;
using ::i;
int main() {}

我使用不同的编译器得到不同的结果:

根据c ++标准,该程序是否格式正确或格式不正确?需要参考c ++标准。

我试图找出应该提交错误的编译器。

2 个答案:

答案 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)是所有的集合   mX的声明和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)成为所有的集合   mX的声明以及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   及其内联命名空间集。   

  给定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。上述引用中显示了使用声明作为上下文的唯一区别,并不影响既定结论。