以下代码有效吗?
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。