2010-08-14 645 views
15

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

我使用MSVC++经由在Win32 VS 2008(SP1)/ x86的实际问题是(由编译器报告=错误)几个编译错误相关联地使用枚举如类模板参数。由于我的项目不幸已变得有点复杂(你可以认为这是一个设计错误:P),引发这些错误的模板类是派生的,嵌套的,甚至专用于带有枚举模板参数的类。

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

使用int而不是枚举,我的项目编译W/O错误。

在此先感谢您的任何提示或提示!


编辑

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

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

+3

“试图编译时,编译器会报告许多错误/无用的错误”这些“无用的”错误通常会对错误和错误进行非常详细的描述。只要阅读编译器输出,而不是“错误列表”。 – SigTerm 2010-08-14 23:08:04

+0

感谢提示,但我做到了。我总是这么做^^ 但它没有帮助我...错误:错误C2059:语法错误:'公共'错误C2143:语法错误:缺少'>'之前';'错误C2143:语法错误:缺少';'之前'}'致命错误C1004:发现意外的文件结束(然后一些其他错误,与此问题无关)所有这些仅在使用枚举时出现并在使用int时出现消失 – dyp 2010-08-14 23:15:11

+0

这对我来说看起来很完美。这是一个编译器错误或者你的错误,如果你猜测,99.9%的赌注就是你。但是,您发布的代码段没有任何问题。请发布一个完整的小样本,以及它创建的确切编译器错误。 – Omnifarious 2010-08-14 23:18:47

回答

4

参照原题:

are there any restrictions/problems using an enum as template (type) argument in 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 specialisation
int specialisation

对于这些简单的例子,一切工作正常,并预期和枚举完美的作品为任何其他类型的模板类型争论(=我没有看到任何问题的原因)。

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

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

0

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

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

编辑:仔细观察你说的那个例子确实重现bug。直到你制作一个例子,我们和其他任何人都不能帮助你。

+0

可以证明编译器只有两种方式存在缺陷: a)根据相关标准验证 b)读取文档并检查它是否是已知问题/缺陷 – Chubsdad 2010-08-15 03:07:03

+0

OP isn' t虽然提供了enum * value *作为模板参数,但是enum * type *是参数。 – 2010-08-15 11:56:49

7

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

A local type, a type with no linkage, an unnamed type or a type compounded from any of these types shall not be used as a template-argument for a template type-parameter.

不能使用匿名枚举作为模板参数,所以下面的代码是无效的C++ 03:

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

enum {A}; 

int main() { 
    f(A); 
} 

它是有效的在C++ 11中。