繁体   English   中英

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

[英]Using enum as template type argument in C++

在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&param by _t(即复制参数),但我也无法解决所有这些错误,也不知道为什么这个“帮助” 。 **我知道,上面的简单例子编译没有错误。

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

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


编辑

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

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

是的,有限制。 例如,根据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中有效。

参考原始问题:

在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。

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

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

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

编辑 :仔细观察你说的那个例子重现bug。 在你做出一个例子之前,我们或其他任何人都无法帮助你。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM