Using enum as template type argument in C++

dyp picture dyp · Aug 15, 2010 · Viewed 29.1k times · Source

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

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.

Using int instead of enum, my project compiles w/o errors.

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.

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 is the compiler?

Answer

vitaut picture vitaut · Jul 3, 2014

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

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:

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

enum {A};

int main() {
  f(A);
}

It is valid in C++11 though.