Supongamos que tengo una función de plantilla y dos clases
class animal {
}
class person {
}
template<class T>
void foo() {
if (T is animal) {
kill();
}
}
¿Cómo hago la verificación para T es animal? No quiero tener algo que verifique durante el tiempo de ejecución. Gracias

Respuestas:
Utilizar
is_same:#include <type_traits> template <typename T> void foo() { if (std::is_same<T, animal>::value) { /* ... */ } // optimizable... }Sin embargo, por lo general, ese es un diseño totalmente inviable y realmente desea especializarse :
template <typename T> void foo() { /* generic implementation */ } template <> void foo<animal>() { /* specific for T = animal */ }Tenga en cuenta también que es inusual tener plantillas de funciones con argumentos explícitos (no deducidos). No es inaudito, pero a menudo hay mejores enfoques.
fuente
Tno se deduce, no hay mucho que puedas hacer. Puede dejar la plantilla principal sin implementar y crear una especialización, o puede agregar una aserción estática conis_same.Creo que hoy en día es mejor usarlo, pero solo con C ++ 17.
#include <type_traits> template <typename T> void foo() { if constexpr (std::is_same_v<T, animal>) { // use type specific operations... } }Si usa algunas operaciones específicas de tipo en el cuerpo de la expresión if sin
constexpr, este código no se compilará.fuente
std::is_same<T, U>::valuepodría usar más corto:std::is_same_v<T, U>En C ++ 17, podemos usar variantes .
Para usar
std::variant, debe incluir el encabezado:#include <variant>Después de eso, puede agregar
std::variantsu código de esta manera:using Type = std::variant<Animal, Person>; template <class T> void foo(Type type) { if (std::is_same_v<type, Animal>) { // Do stuff... } else { // Do stuff... } }fuente
typeque es el valor de tipoTypeo una plantilla que no tiene sentido aquí)is_same_vno es significativo en el contexto devariant. El "rasgo" correspondiente esholds_alternative.std::variantes totalmente innecesario aquíPuede especializar sus plantillas en función de lo que se pasa a sus parámetros de esta manera:
template <> void foo<animal> { }Tenga en cuenta que esto crea una función completamente nueva basada en el tipo que se pasa como
T. Esto suele ser preferible ya que reduce el desorden y es esencialmente la razón por la que tenemos plantillas en primer lugar.fuente