以下代码是否有效?
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都接受它。 这是标准行为吗?将赞赏对工作草案/标准的参考。
答案 0 :(得分:4)
关于using X = X
是否应该选择被定义的X
或可能已经在范围内的X
,存在争议。为避免“未知类型”并使其与typedef
类似,我们认为正在定义的X
在其待分配的类型表达式中不可见(所以而不是与int x = x
类似,它类似于typedef x x;
)。
回想一下,typedef
只是一个普通的声明,前面加上typedef
关键字。第一次提到X
并没有声明任何内容,只是说明了什么类型的别名。如果委员会决定采用using X = X
, 可以1>}更早宣布X
,这是主要区别。
但请注意,您的代码具有有效的未定义行为,因为它违反了没有必需诊断的规则。 3.3.7p1b2
在类S中使用的名称N应在其上下文中引用相同的声明,并在完成的S范围内重新评估。违反此规则不需要诊断。
答案 1 :(得分:2)
在typedef
声明中,最终名称是声明的名称,这是声明的要点。因此,第一个X
出现在D2::X
声明之前,因此会解析为B::X
。