16

在 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'”。其中许多我可以通过用 _t 替换类似于示例中的 const _t& 参数的方法来修复(即复制参数),但我既不能修复所有这些错误,也不知道为什么这个“有帮助” . **我知道,上面的简单示例编译时没有错误。

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

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


编辑

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

我已经遇到了一些编译器错误(我猜在 20k 行代码内有 2 或 3 个),但在我看来,这个错误很奇怪。
任何建议如何确定它是否是编译器?

4

3 回答 3

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 中有效。

于 2014-07-03T17:49:10.213 回答
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;
}

输出是:

MyEnum 特化
int特化

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

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

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

于 2010-08-15T14:47:33.170 回答
0

MSVC 奇怪地处理枚举(值)模板参数。枚举有时会被不当提升,int并且操作符定义不正确。似乎他们并没有真正用enum类型测试模板引擎。

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

编辑:仔细检查后,您说该示例不会重现该错误。在您提供一个可以帮助您的示例之前,我们或其他任何人都无法帮助您。

于 2010-08-15T00:46:48.853 回答