Especialização de modelos para enum
-
06-07-2019 - |
Pergunta
É possível especializar um método templatizado para enums?
Algo como (o código inválido abaixo):
template <typename T>
void f(T value);
template <>
void f<enum T>(T value);
No caso não é possível, supondo que tenho especializações para vários tipos, como int
, unsigned int
, long long
, unsigned long long
, etc, então qual das especializações um valor de enumeração usará?
Solução
Você pode usar std::enable_if
com std::is_enum
a partir de <type_traits>
Para fazer isso.
Em uma resposta a uma das minhas perguntas, Litb postou um muito Explicação detalhada e bem escrita de como isso pode ser feito com os equivalentes de impulso.
Outras dicas
Não tenho certeza se entendi sua pergunta corretamente, mas você pode instanciar o modelo em enumes específicos:
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);
}
Presumivelmente, a única coisa interessante que você poderia fazer com um tipo que eles únicos que você sabe sobre isso é que é uma enumeração, é lançá -lo ao seu tipo subjacente e operar nisso. Veja como isso pode ser, usando a abordagem sugerida de James (também conhecida como 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));
}
Como um bônus relacionado, aqui está um método semelhante que só seria resolvido para um tipo específico de sua escolha (substitua o bool em is_same
para o tipo de sua escolha):
template<typename T>
typename std::enable_if<std::is_same<T,bool>::value, void>::type
Baz(T bl)
{
if (bl)
{
//...
}
else
{
//...
}
}