views:

244

answers:

2

Hi,

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 [edit:] , but unfortunately I could not reproduce the error, that's why I'm asking for any known restrictions / problems... when I succeed in reproducing it, I'll edit the question.[/edit]

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

Thanks in advance for any hint or tip!

p.s.: I know C++ is not that type safe, but I'd appreciate using enum over int and I'm interested in the reasons that caused all the trouble I had.




[edit 2:]
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 o.O
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?
[/edit]

A: 

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.

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 not reproduce the bug. Neither we nor anyone else can help you until you produce an example that does.

Potatoswatter
One can prove that a compiler has a bug only by two ways:a) validate against the relevant Standardsb) Reading the documentation and checking if it is a known issue/defect
Chubsdad
@PotatoSwatter: The OP isn't supplying an enum *value* as the template parameter though - the enum *type* is the parameter.
jon hanson
+1  A: 

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.

DyP