Using enum as template type argument in C++

别来无恙 提交于 2019-12-20 17:41:16

问题


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?


回答1:


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.




回答2:


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.




回答3:


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.



来源:https://stackoverflow.com/questions/3485472/using-enum-as-template-type-argument-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!