在C ++中使用enum作为模板类型参数

时间:2010-08-14 23:04:42

标签: c++ templates enums visual-c++-2008

在C ++中使用枚举作为模板(类型)参数是否存在任何限制/问题?

示例:

enum MyEnum
{
    A, B, C, D, E
};

template <typename _t>
class MyTemplate
{
public:
   _t value;

   void func(const _t& param) { /* .... */ }
};

// ....

MyTemplate<MyEnum> MyInstance;

我在Win32 / x86上通过VS 2008(SP1)使用MSVC ++的实际问题是与使用枚举作为模板参数的类相关联的几个编译错误(=编译器报告的错误)。遗憾的是,我的项目变得有点复杂(您可以将其视为设计错误:P),引发,嵌套甚至专门针对具有枚举模板参数的类的模板类会引发这些错误。

尝试构建时,编译器会在只有注释的行中报告许多错误/无用的错误,例如“C2059:语法错误:'public'”。其中许多我可以通过替换类似于示例中的方法const _t&amp; amp; param by _t(即复制参数),但我既不能修复所有这些错误,也不知道为什么这有“帮助”。 **我知道,上面的简单例子编译没有错误。

使用int而不是enum,我的项目编译没有错误。

提前感谢任何提示或提示!


修改

毕竟,我认真考虑这是一个编译器错误。当我尝试使用简化代码重现错误时,我只在50%的“构建”中获得它们,而不是非常确定: 例如。试图编译,并报告了这些错误。重建 - 没有变化。删除评论,构建 - 没有变化。重建 - 然后:没有错误,编译好。

我已经遇到了一些编译器错误(我估计在20k行代码中有2或3个),但这个看起来很奇怪。
有任何建议如何判断编译器?

3 个答案:

答案 0 :(得分:7)

是的,有限制。例如,根据C ++ 03 14.3.1[temp.arg.type]/2

,您不能使用匿名枚举作为模板参数
  

本地类型,没有链接的类型,未命名的类型或从这些类型中复合的类型不得用作模板类型参数的模板参数。

因此以下代码在C ++ 03中无效:

template <typename T>
void f(T) {}

enum {A};

int main() {
  f(A);
}

它在C ++ 11中有效。

答案 1 :(得分:4)

参考原来的问题:

  

在C ++中使用枚举作为模板(类型)参数是否存在任何限制/问题?

我没有发现任何 - 我认为没有。它可能会成为一个坏主意,因为这种技术经常不被使用,因此可能会有一些(更多)编译器错误与此相关,就像Potatoswatter所说的那样。 请考虑以下示例:

enum MyEnum : int
{
    A, B, C, D
};

template <typename _t> class MyTemplate
{
public:
    void print()
    {
        cout << "not using any specialisation" << endl;
    }
};
    template <> class MyTemplate <MyEnum>
    {
    public:
        void print()
        {
            cout << "MyEnum specialisation" << endl;
        }
    };
    template<> class MyTemplate <int>
    {
    public:
        void print()
        {
            cout << "int specialisation" << endl;
        }
    };

template <typename _t> void print(_t param)
{
    MyTemplate<_t> m;
    m.print();
}


int main()
{
    print(A);
    print(5);

    return 0;
}

输出结果为:

  

MyEnum专业化   int专业化

对于这些简单的例子,一切正常并且符合预期,并且枚举与任何其他类型的模板类型参数一样完美(=我没有看到任何问题的原因)。

最初,我在问题中引入了示例,以显示我对该问题的意义(枚举作为模板类型参数,显示可能的用法作为成员或方法参数类型等)。为了提供一些背景知识,即为什么我问了这个问题(想象一下我问“int有什么问题”),我提到了编译我的实际项目的这些奇怪的问题。
对不起,我无法提取它本身完整的片段并重现错误,至少我能得到的是2k行代码分成4个文件,其中“语法错误:'公共'”和其他一些编译项目时引发了语法错误,在删除注释或重新构建(=删除中间文件)时,它们在某些情况下出现/消失。不幸的是,重建对原始项目没有帮助,我不得不将枚举类型中的特化替换为int

所以,感谢大家的提示和技巧。在我看来,潜在的问题是编译器错误,是什么让这个问题毫无意义,因为答案似乎只是“没有 - 使用枚举作为模板类型参数没有限制”。很抱歉给您带来不便。

答案 2 :(得分:0)

MSVC奇怪地处理枚举(值)模板参数。枚举有时会被不正确地提升为int,并且未正确定义运算符。看起来他们并没有真正用enum类型测试模板引擎。

证明这是一个编译器错误很简单:将有效代码放入并观察它是否成功编译。 你的例子显然是合规的,所以问题(或错误,无论如何)是他们的。

编辑:仔细检查一下,您说该示例重现该错误。在你制作一个例子之前,我们或其他任何人都无法帮助你。