2009-10-25 4 views
7

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

Нечто подобное (неверный код ниже):

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

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

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

+0

http://stackoverflow.com/questions/29762892/how-to-specialize-a-template-function-for-enum-and-specific-type –

ответ

19

std::enable_ifstd::is_enum от <type_traits> для этого.

In an answer to one of my questions, litb опубликовано очень подробное и хорошо написанное объяснение того, как это можно сделать с эквивалентами Boost.

+0

Это выглядит как это может сработать. Я смотрю на это. Благодаря! – nilton

6

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

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); 
} 
+2

Это не работает, потому что у меня нет типа перечисления заранее. – nilton

+0

в C++ 11 у вас есть тип и, следовательно, вы можете создать шаблон перечисления. Более приятной темой будет создание шаблона, основанного на определенных значениях перечисления (f ). все еще возможно с помощью какого-то трюка или его можно избежать, просто объявив классы вместо значений перечисления. – GameDeveloper

1

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

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

template<typename T> 
typename std::enable_if<std::is_same<T,bool>::value, void>::type 
Baz(T bl) 
{ 
    if (bl) 
    { 
     //... 
    } 
    else 
    { 
     //... 
    } 
} 
Смежные вопросы