【问题标题】:Point of declaration of typedef/alias declarationtypedef/alias 声明的声明点
【发布时间】:2012-11-18 21:12:06
【问题描述】:
以下代码有效吗?
struct B{ using X=int; };
struct D1:B{ using X=X; }; // (1)
struct D2:B{ typedef X X; }; // (2)
我希望 D2::X 的声明点位于 (2) 中的两个 X 之间,但 gcc 4.8 和 clang 3.2 似乎都接受它。
这是标准行为吗?对工作草案/标准的参考将不胜感激。
【问题讨论】:
标签:
c++
c++11
typedef
language-lawyer
【解决方案1】:
关于 using X = X 是否应该选择正在定义的 X 或可能已经在范围内的 X 存在争议。为避免“未知类型”并使其与typedef 相似,裁定被定义的X 在其待分配的类型表达式中不可见(so 而不是类似于@ 987654326@,类似于typedef x x;)。
回想一下,typedef 只是一个带有 typedef 关键字的普通声明。第一次提到X 并没有声明任何东西,它只是说什么类型会被别名。这是与using X = X 的主要区别,如果委员会决定这样做的话,可以提前声明X。
但请注意,您的代码具有实际上未定义的行为,因为它违反了不需要诊断的规则。 3.3.7p1b2
在类 S 中使用的名称 N 应在其上下文中引用相同的声明,并且在 S 的完整范围内重新评估时。违反此规则不需要诊断。
【解决方案2】:
在typedef 声明中,最终名称是被声明的名称,这就是声明点。所以第一个X 出现在D2::X 的声明之前,因此解析为B::X。