Using enum as template type argument in C++

前端 未结 3 1963
一生所求
一生所求 2021-02-07 09:29

are there any restrictions / problems using an enum as template (type) argument in C++?

Example:

enum MyEnum
{
    A, B, C, D, E
};

template 

        
相关标签:
3条回答
  • 2021-02-07 10:17

    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.

    0 讨论(0)
  • 2021-02-07 10:23

    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.

    0 讨论(0)
  • 2021-02-07 10:24

    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.

    0 讨论(0)
提交回复
热议问题