Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template specialization for enum

Is it possible to specialize a templatized method for enums?

Something like (the invalid code below):

template <typename T>
void f(T value);

template <>
void f<enum T>(T value);

In the case it's not possible, then supposing I have specializations for a number of types, like int, unsigned int, long long, unsigned long long, etc, then which of the specializations an enum value will use?

like image 245
nilton Avatar asked Oct 25 '09 04:10

nilton


3 Answers

You can use std::enable_if with std::is_enum from <type_traits> to accomplish this.

In an answer to one of my questions, litb posted a very detailed and well-written explanation of how this can be done with the Boost equivalents.

like image 58
James McNellis Avatar answered Oct 14 '22 04:10

James McNellis


I'm not sure if I understand your question correctly, but you can instantiate the template on specific enums:

template <typename T>
void f(T value);

enum cars { ford, volvo, saab, subaru, toyota };
enum colors { red, black, green, blue };

template <>
void f<cars>(cars) { }

template <>
void f<colors>(colors) { }

int main() {
    f(ford);
    f(red);
}
like image 29
Thomas Padron-McCarthy Avatar answered Oct 14 '22 02:10

Thomas Padron-McCarthy


Presumably, the only interesting thing you could do with a type that they only thing you know about it is that it's an enum, is cast it to its underlying type and operate on that. Here's how that might look like, using James' suggested approach (AKA SFINAE):

void Bar(int b); // and/or other underlying types

template<typename T>
typename std::enable_if<std::is_enum<T>::value, void>::type
Foo(T enm)
{
    Bar(static_cast<typename std::underlying_type<T>::type>(enm));
}

As a related bonus, here's a similar method that would only get resolved for a specific type of your choosing (replace bool in is_same to the type of your choosing):

template<typename T>
typename std::enable_if<std::is_same<T,bool>::value, void>::type
Baz(T bl)
{
    if (bl)
    {
        //...
    }
    else
    {
        //...
    }
}
like image 22
Ohad Schneider Avatar answered Oct 14 '22 02:10

Ohad Schneider