在 C++ 中使用枚举作为模板类型参数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3485472/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using enum as template type argument in C++
提问by dyp
are there any restrictions / problems using an enum as template (type) argument in C++?
在 C++ 中使用枚举作为模板(类型)参数有任何限制/问题吗?
Example:
例子:
enum MyEnum
{
A, B, C, D, E
};
template <typename _t>
class MyTemplate
{
public:
_t value;
void func(const _t& param) { /* .... */ }
};
// ....
MyTemplate<MyEnum> MyInstance;
My actual problem using MSVC++ via VS 2008 (SP1) on Win32/x86 are several compilation errors (= errors reported by the compiler) in association with classes using enums as template arguments. As my project unfortunately has become a bit complex (you can consider that as a design error :P), the template classes raising these errors are derived, nested and even specialised on a class with enum template parameter.
我在 Win32/x86 上通过 VS 2008 (SP1) 使用 MSVC++ 的实际问题是与使用枚举作为模板参数的类相关的几个编译错误(= 编译器报告的错误)。不幸的是,由于我的项目变得有点复杂(您可以将其视为设计错误:P),引发这些错误的模板类是派生的、嵌套的,甚至专门用于具有枚举模板参数的类。
Trying to build, the compiler reports many wrong/useless errors such as "C2059: syntax error: 'public'" in lines where there is only a comment. Many of them I could fix by replacing in methods similar to the one in the example the const _t& param by _t (i.e. copying the parameter), but neither could I fix all of these errors nor do I have a clue why this "helps". **I know, the simple example above compiles w/o errors.
尝试构建时,编译器在只有注释的行中报告了许多错误/无用的错误,例如“C2059:语法错误:'public'”。其中许多我可以通过替换类似于示例中的方法来修复 const _t& param by _t(即复制参数),但我既无法修复所有这些错误,也不知道为什么这“有帮助” . **我知道,上面的简单例子编译没有错误。
Using int instead of enum, my project compiles w/o errors.
使用 int 而不是 enum,我的项目编译时没有错误。
Thanks in advance for any hint or tip!
提前感谢您的任何提示或提示!
Edit:
编辑:
After all, I seriously consider this as a compiler bug. When I tried to reproduce the errors with simplified code, I got them only in 50 % of all "builds", not very deterministic:
E.g. tried to compile, and it reported these errors. Rebuild - no change. Deleted a comment, build - no change. Rebuild - and then: no errors, compiles fine.
毕竟,我认真地认为这是一个编译器错误。当我尝试用简化的代码重现错误时,我只在所有“构建”的 50% 中得到它们,不是很确定:
例如,尝试编译,它报告了这些错误。重建 - 没有变化。删除了评论,构建 - 没有变化。重建 - 然后:没有错误,编译正常。
I've already met a few compiler bugs (2 or 3 I guess within 20k lines of code), but this one seems to me very strange.
Any suggestions how to figure out if it isthe compiler?
我已经遇到了一些编译器错误(我猜在 20k 行代码内有 2 或 3 个),但是这个错误在我看来很奇怪。
任何建议如何确定它是否是编译器?
采纳答案by dyp
Referring to the original question:
参考原问题:
are there any restrictions / problems using an enum as template (type) argument in C++?
在 C++ 中使用枚举作为模板(类型)参数有任何限制/问题吗?
I didn't find any - and I don't think there are any. It might turn out to be a bad idea because this technique it is not used that often, so there might be a few (more) compiler bugs relating to this, just as Potatoswatter said.
Consider the following example:
我没有找到 - 而且我认为没有。这可能是一个坏主意,因为这种技术并不经常使用,所以可能有一些(更多)编译器错误与此相关,正如 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;
}
The output is:
输出是:
MyEnum specialisation
int specialisation
MyEnum 专业化
int 专业化
For these simple examples, everything works fine and as expectedand the enum works perfectly as any other type as template type argument (= I don't see any reason for problems).
Originally, I introduced the example in the question to show what I meant with that question (enum as template type argument, show possible usages as member or method argument type and so on). To provide a bit of background, i.e. whyI asked that question (imagine I asked "are there any problems with int"), I mentioned these strange problems compiling my actual project.
I'm sorry I could not extract a snippet of it that is complete in itself and reproducing the errors, the least I could get were 2k lines of code splitted into 4 files, where a "syntax error : 'public'" and some other syntax error were raised when I compiled the project, and they appeared / disappeared under certain circumstances, when deleting a comment or re-building (= deleting the intermediate files). Unfortunately, rebuilding does not help with the original project, where I had to replace a specialisation from an enum type to int.
对于这些简单的示例,一切正常且符合预期,并且枚举与任何其他类型作为模板类型参数完美地工作(= 我没有看到任何问题的原因)。
最初,我在问题中引入了示例以说明我对该问题的含义(枚举作为模板类型参数,显示可能的用法作为成员或方法参数类型等)。为了提供一些背景知识,即为什么我问这个问题(想象一下我问“int 有没有问题”),我提到了编译我的实际项目时出现的这些奇怪的问题。
对不起,我无法提取它本身完整的片段并重现错误,我至少能得到 2k 行代码分成 4 个文件,其中“语法错误:'public'”和其他一些编译项目时出现语法错误,并且在某些情况下,删除注释或重新构建(= 删除中间文件)时它们会出现/消失。不幸的是,重建对原始项目没有帮助,在那里我不得不将特殊化从枚举类型替换为 int。
So, thanks everyone for your hints and tips. The underlying problem seems to me to be a compiler bug, what makes the question a bit pointless, as the answer seems to be just "no - there are no restrictions using an enum as template type argument". Sorry for the inconvenience.
所以,感谢大家的提示和技巧。在我看来,潜在的问题是编译器错误,是什么让这个问题变得毫无意义,因为答案似乎只是“不 - 使用枚举作为模板类型参数没有任何限制”。带来不便敬请谅解。
回答by vitaut
Yes, there are restrictions. For example, you cannot use an anonymous enum as a template argument according to C++03 14.3.1[temp.arg.type]/2
是的,有限制。例如,根据 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.
局部类型、没有链接的类型、未命名的类型或由这些类型中的任何一种复合的类型不应用作模板类型参数的模板参数。
So the following code is not valid in C++03:
所以以下代码在 C++03 中无效:
template <typename T>
void f(T) {}
enum {A};
int main() {
f(A);
}
It is valid in C++11 though.
虽然它在 C++11 中有效。
回答by Potatoswatter
MSVC handles enum (value) template parameters strangely. Enums are promoted to int
improperly sometimes and the operators aren't defined properly. It seems that they don't really test the template engine with enum
types.
MSVC 奇怪地处理枚举(值)模板参数。枚举int
有时会被不正确地提升,并且运算符没有正确定义。似乎他们并没有真正用enum
类型测试模板引擎。
Proving it's a compiler bug is simple: put valid code in and observe whether it successfully compiles. Your example is obviously compliant, so the problem (or the mistake, anyway) is theirs.
证明它是一个编译器错误很简单:放入有效的代码并观察它是否成功编译。你的例子显然是合规的,所以问题(或错误,无论如何)是他们的。
Edit: on closer inspection you say that the example does notreproduce the bug. Neither we nor anyone else can help you until you produce an example that does.
编辑:仔细检查后,您说该示例没有重现该错误。我们或其他任何人都无法帮助您,直到您提供一个可以帮助您的示例。