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