c++templatesenumsvisual-c++-2008

Using enum as template type argument in C++


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?


Solution

  • Referring to the original question:

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

    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

    For these simple examples, everything works fine and as expected and 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. why I 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.

    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.