Шаблон специализации для enum - PullRequest
8 голосов
/ 25 октября 2009

Можно ли специализировать шаблонный метод для перечислений?

Что-то вроде (неверный код ниже):

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

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

В случае, если это невозможно, тогда предположим, что у меня есть специализации для ряда типов, таких как int, unsigned int, long long, unsigned long long и т. Д., То, какую из специализаций будет использовать значение enum

Ответы [ 3 ]

20 голосов
/ 25 октября 2009

Для этого можно использовать std::enable_if с std::is_enum из <type_traits>.

В ответ на один из моих вопросов Литб опубликовал очень подробное и хорошо написанное объяснение того, как это можно сделать с помощью эквивалентов Boost.

7 голосов
/ 25 октября 2009

Я не уверен, правильно ли я понимаю ваш вопрос, но вы можете создать экземпляр шаблона для конкретных перечислений:

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);
}
1 голос
/ 01 декабря 2016

Предположительно, единственная интересная вещь, которую вы можете сделать с типом, о котором они знают только то, что он - это перечисление, приведение его к его базовому типу и работа с ним. Вот как это может выглядеть, используя предложенный Джеймсом подход (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));
}

В качестве связанного бонуса, вот аналогичный метод, который будет разрешен только для определенного типа по вашему выбору (замените bool в is_same на тип по вашему выбору):

template<typename T>
typename std::enable_if<std::is_same<T,bool>::value, void>::type
Baz(T bl)
{
    if (bl)
    {
        //...
    }
    else
    {
        //...
    }
}
...