Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

enum as template

This is what I want to do:

enum MyEnum
{
    ONE = 1, TWO, THREE
};

template<class T>
void func()
{
    cout << T::TWO << endl;
}

int main()
{
    func<MyEnum>();
};

It works, but I get a warning: "warning C4482: nonstandard extension used: enum 'MyEnum' used in qualified name"

How can I do this without getting the warning

like image 942
hidayat Avatar asked Feb 10 '11 14:02

hidayat


3 Answers

Enum is a little tricky here. The type ONE and TWO will be in the outer namespace. So adding the type to the name results in the warning. You could just remove the qualifier

template<class T>
void func()
{
    cout << TWO << endl;
}

Since the TWO is known in the outer namespace. You could also just move your enum to some sort of enclosing struct.

struct EnumContainer
{
    enum MyEnum
    {
        ONE = 1, TWO, THREE
    };
};

template<class T>
void func()
{
    std::cout << T::TWO << std::endl;
}

int main()
{
    func<EnumContainer>();
};

Now the compiler should be fine.

like image 140
mkaes Avatar answered Nov 19 '22 14:11

mkaes


Enums (pre C++0x) are treated like integral types.

In fact, the notation MyEnum::TWO is garbage: there is no class or namespace MyEnum. The names ONE, TWO, and THREE are brought into the namespace where the enum is defined [in this case, the global namespace].

You should get an error like TWO is not a member of MyEnum.

One way to emulate the behavior is to put it in a struct or class, like others have suggested.

like image 25
Foo Bah Avatar answered Nov 19 '22 15:11

Foo Bah


While it would be nice to use the enum as the template parameter and have it recognize each individual enum separately as you've written it, it won't happen. Instead, may I suggest that you declare the following:

template<MyEnum T>
void func(){
    std::cout << T << std::endl;
}

The great thing about C++ is that the way templates are structured gives you a Turning complete system. Hence, you don't need a separate call like this, as you've declared to get each individual enum value. You can create a separate function for each value when you need it and only when you need it.

Now, getting to the other problem of your question, as @delnan commented, you can't have two different Enums with the same name. You can, however, have a class with a member variable called TWO such that:

struct Foo{
    int TWO;
};

struct Bar{
    int TWO;
};

template<typename T>
void func(){
    std::cout << T::TWO << std::endl;
}

Hope that helps.

like image 1
wheaties Avatar answered Nov 19 '22 16:11

wheaties