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

dyp*_*dyp 16 c++ enums templates 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;
Run Code Online (Sandbox Code Playgroud)

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

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

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

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


编辑:

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

我已经遇到了一些编译器错误(我估计在20k行代码中有2或3个),但这个在我看来非常奇怪.
任何建议如何弄清楚它是否是编译器?

vit*_*aut 7

是的,有限制.例如,根据C++ 03,您不能使用匿名枚举作为模板参数14.3.1[temp.arg.type]/2

本地类型,没有链接的类型,未命名的类型或从这些类型中的任何类型复合的类型不应该用作模板类型参数的模板参数.

所以下面的代码在C++ 03中无效:

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

enum {A};

int main() {
  f(A);
}
Run Code Online (Sandbox Code Playgroud)

它在C++ 11中有效.


dyp*_*dyp 5

参考原问题:

在 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;
}
Run Code Online (Sandbox Code Playgroud)

输出是:

MyEnum 专业化
int 专业化

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

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

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