6

根据 c++ 标准,以下程序是格式正确的还是格式错误的?

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

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

根据 c++ 标准,这个程序是格式正确的还是格式错误的?需要对 c++ 标准的引用。

我试图弄清楚我应该为哪个编译器提交错误。

4

2 回答 2

5

格式良好。

using 指令不会在全局命名空间中引入名称i,但会在查找期间使用。using-declaration使用合格的查找来查找i;在 [3.4.3.2 p1, p2] 中指定了存在using 指令的合格查找(引自 N4527,当前工作草案):

如果qualified-id的nested-name-specifier 指定了一个命名空间(包括nested-name-specifier为的情况,即指定全局命名空间),则在 nested-name-specifier之后指定的名称在命名空间的范围。[...]::

对于命名空间X和名称m,命名空间限定的查找集 S(X,m)定义如下:令S'(X,m)m是in的所有声明和(7.3.1)X的内联命名空间集的集合X. 如果 S'(X,m)不为空,则S(X,m)S'(X,m);否则,S(X,m)S(N i ,m)对于使用指令in指定的所有名称空间N i及其内联名称空间集的并集。X

因此,对于合格的查找,第一步是i直接在由嵌套名称说明符::在本例中)指示的命名空间中查找 made 的声明。没有这样的声明,所以lookup接着进行第二步,即在全局命名空间中由using-directivesi指定的所有命名空间中形成由限定的lookup找到的所有声明的集合。该集合由 组成,它是名称查找的结果,并通过 using 声明作为名称引入全局命名空间。N::i

我发现值得注意(虽然很明显)这个限定查找的定义是递归的:使用引用中的符号,每个命名空间N i中的限定查找将首先查找直接在N i中进行的声明,然后,如果没有找到, 将依次继续查找由N i中的using 指令指定的命名空间,依此类推。


对于它的价值,MSVC 也接受代码。

于 2015-07-25T17:12:54.820 回答
4

海湾合作委员会是错误的。合格名称查找确实考虑N::i;§3.4.3.2/2 和 /3:

对于命名空间X和名称m,命名空间限定的查找集 S(X, m)定义如下: 令为inS'(X, m)的所有声明和 (7.3.1)的内联命名空间集的集合。如果不为空,则为; 否则,i的并集,用于通过 using 指令 ​​in 指定的所有命名空间 及其内联命名空间集。 给定(哪里是用户声明的命名空间),或给定(哪里 是全局命名空间),[...] 如果只有一个成员,或者如果引用的上下文是使用声明(7.3.3),mXXS'(X, m)S(X, m)S'(X, m)S(X, m)S(N, m)NX

X::mX::mXS(X, m)S(X, m)是 的必需声明集m

在你的程序中只有一个使用指令指定的命名空间:N. 因此它被包含在联合中并被::i解决为N::i.

请注意,GCC 与其查找不一致:::i在另一个上下文中使用是可以的。

namespace N { int i; }
using namespace N;

int main() {
    ::i = 5;
}

编译. 使用声明作为上下文的唯一区别显示在上面的引用中,并且不影响既定结论。

于 2015-07-25T17:12:15.897 回答