我正在使用clang编译以下测试代码:
template<typename T> struct S1
{
struct S2{
enum class E1;
enum class E2: T;
enum class E3: short;
};
typename S2::E1 b1;
typename S2::E2 b2;
typename S2::E3 b3;
enum class S1::S2::E1 {e11,e12};
enum class S1::S2::E2 : T {e21,e22};
enum class S1::S2::E3 : short {e31,e32};
};
template struct S1<int>;
我收到错误:模板特化或定义需要与嵌套类型'S1&lt;对应的模板参数列表。 T>'。我的猜测是因为在
中添加成员时正在定义struct S1enum class S1::S2::E1 {e11,e12}
enum class S1::S2::E2 : T {e21,e22};
enum class S1::S2::E3 : short {e31,e32};
编译器不知道什么是T,因为S1尚未实例化,因此T无法解析。因此编译器不知道枚举成员的大小,因此抛出错误。它是否正确?是否在标准中规定了?
注意:gcc不会抛出任何此类错误。
答案 0 :(得分:1)
根本不允许定义这样的enum
。 n3337第7.2 / 4段指出:
如果 enum-key 后面跟着嵌套名称指定程序,枚举指定程序应引用一个枚举, 先前已直接在嵌套名称指定者所指的类或命名空间中声明(即, 既不是由 using-declaration 继承或引入的, enum-speci fi er 也应出现在命名空间中 附上先前的声明。
当然,错误信息并不完全是明星。您的示例可以大大简化为:
template<typename T> struct S1
{
struct S2 {
enum class E;
};
enum class S2::E {};
};
将产生相同的错误消息。
有效选项包括:
// definition in the scope that the declaration appears in
template<typename T> struct S1
{
struct S2 {
enum class E;
enum class E {};
};
};
或
// definition in the enclosing namespace scope
template<typename T> struct S1
{
struct S2 {
enum class E;
};
};
template<typename T>
enum class S1<T>::S2::E {};
同样的规则也适用于嵌套类(见9.7 / 3)。如果你试试这个
template<typename T>
struct S1
{
struct S2 {
struct S3;
};
struct S2::S3 {};
};
然后GCC也会产生一个(同样没有帮助的)错误。它与枚举不相同似乎是一个错误。
你自己为错误提出的解释是不正确的。在模板的定义中,编译器不需要(并且显然不能)知道T
是什么。它只在实例化模板时才需要它。如果像template<typename T> struct X { T obj; };
那样有什么用呢?