代码之家  ›  专栏  ›  技术社区  ›  dyp

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

  •  15
  • dyp  · 技术社区  · 14 年前

    例子:

    enum MyEnum
    {
        A, B, C, D, E
    };
    
    template <typename _t>
    class MyTemplate
    {
    public:
       _t value;
    
       void func(const _t& param) { /* .... */ }
    };
    
    // ....
    
    MyTemplate<MyEnum> MyInstance;
    

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


    编辑 :

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

    我已经遇到了一些编译器错误(2或3我猜在20k行代码),但这一个似乎对我来说非常奇怪。
    编译器?

    3 回复  |  直到 7 年前
        1
  •  7
  •   vitaut    10 年前

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

        2
  •  5
  •   dyp    14 年前

    在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;
    }
    

    输出为:


    国际专业化

    对于这些简单的例子, enum与任何其他类型as template类型参数一样工作正常(=我看不出有任何问题的原因)。

    最初,我在问题中引入了这个示例来说明我对这个问题的意思(enum作为模板类型参数,show mable usage作为成员或方法参数类型等等)。提供一点背景,即。 为什么? 我问了那个问题(假设我问“int有什么问题吗”),我提到了编译我的实际项目时遇到的这些奇怪的问题。
    很抱歉,我无法提取一段完整的代码片段并再现错误,至少我可以得到2k行代码,分成4个文件,其中一个“syntax error:'public'”和一些其他语法错误是在我编译项目时提出的,它们在某些情况下出现/消失,删除注释或重新生成(=删除中间文件)时。不幸的是,重建对最初的项目没有帮助,我不得不将一个从enum类型到int类型的专门化替换为int类型。

    “否-使用枚举作为模板类型参数没有限制”

        3
  •  0
  •   Potatoswatter R. Martinho Fernandes    14 年前

    MSVC奇怪地处理enum(value)模板参数。枚举升级为 int 有时不正确,运算符定义不正确。似乎他们并没有真正测试模板引擎 enum 类型。

    你的例子显然是符合的,所以问题(或错误,无论如何)是他们的。

    :仔细观察,你说这个例子确实如此