模板结构中枚举类的动态初始化

时间:2013-09-26 12:24:44

标签: c++ compiler-construction struct enums clang

我正在使用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 S1
enum 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不会抛出任何此类错误。

1 个答案:

答案 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; };那样有什么用呢?