Шаблон специализации для enum
-
06-07-2019 - |
Вопрос
Можно ли специализировать шаблонный метод для перечислений?
Что-то вроде (неверный код ниже):
template <typename T>
void f(T value);
template <>
void f<enum T>(T value);
Если это невозможно, то предположим, что у меня есть специализации для ряда типов, таких как int
, unsigned int
, long long
, unsigned long long
и т. д., то какая из специализаций будет использовать значение enum
Решение
Вы можете использовать std::enable_if
с std::is_enum
из <type_traits>
, чтобы выполнить это.
В ответе на один из моих вопросов litb опубликовал очень подробное и хорошо написанное объяснение того, как это можно сделать с помощью эквивалентов Boost.
Другие советы
Я не уверен, правильно ли я понимаю ваш вопрос, но вы можете создать экземпляр шаблона для конкретных перечислений:
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);
}
Предположительно, единственная интересная вещь, которую вы можете сделать с типом, о котором они знают только то, что он является перечислением, это приведение его к базовому типу и работа с ним. Вот как это может выглядеть, используя предложенный Джеймсом подход (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
{
//...
}
}