该程序不应编译,因为它X::i
在同一块范围内声明了两次。
C++14 §7.3.3/10:
” using-declaration 是一种声明,因此可以在允许(且仅在)允许多个声明的情况下重复使用。[示例:
namespace A {
int i;
}
namespace A1 {
using A::i;
using A::i; // OK: double declaration
}
void f() {
using A::i;
using A::i; // error: double declaration
}
编辑:上面引用的非规范性评论,我认为它回答了这个问题,最初是在 C++98 中,并且在技术勘误 1 (C++03)、C++11 和 C++14 中幸存下来。但显然这是错误的。Richard Smith 在他的回答中引用了关于它的核心问题 36,首先由 Andrew Koenig 于 1998 年 8 月 2日提出(在 ANSI 批准第一个标准后不到一个月),这显然意味着一个已知的不正确评论可以在标准。
引用核心问题本身:
C++ 标准核心语言活动问题,第 36 期:
” 04/00 会议记录:核心语言工作组无法就using-declaration应仿效
哪种声明达成共识。在一次草率投票中,7 名成员赞成在任何可能出现非定义声明的地方允许使用声明,而 4 名成员更倾向于仅在命名空间范围内允许多个using-eclarations(理由是允许多个using-declarations主要是为了支持它在多个头文件中的使用,这些头文件很少包含在命名空间范围以外的任何地方)。John Spicer 指出声明可以在类范围内出现多次,并询问是否使用声明friend
在“类似声明”决议下将具有相同的属性。
由于缺乏协议,该问题被恢复为“开放”状态。
C++98 和 C++14 的 §3.3.1/4 中对同名的多个声明进行了一般性讨论。据我所见,C++14 文本与原始 C++98 文本一字不差。并且它本身允许在许多情况下在同一个声明区域中多次声明相同的名称,其中之一是所有声明都引用同一个实体:
C++14 §3.3.1/4:
”给定单个声明区域中的一组声明,每个声明都指定相同的非限定名称,
但是,这里的措辞只说明了不直接无效的内容。一个声明可以被其他规则禁止,即使它没有被这条规则禁止。例如,对类成员声明有这样的限制:
C++14 §9.2/1:
” [...] 成员不得在成员规范中声明两次,除非可以声明嵌套类或成员类模板,然后再定义,并且可以使用opaque-enum-declaration和后来用enum-specifier重新声明。
我找不到支持上面开头引用的 C++14 §7.3.3/10 中明显不正确的注释的这种限制,即我找不到对块作用域或命名空间作用域的任何特殊处理,因此暂定结论(请记住,尽管在 1998 年就已经存在争议,但该评论仍然存在)是有争议的评论实际上是错误的,并且该问题的代码,其中同一声明区域中的两个声明引用同一实体,是有效的并且应该被接受由所有编译器。