Supposons que j'ai une fonction de modèle et deux classes
class animal {
}
class person {
}
template<class T>
void foo() {
if (T is animal) {
kill();
}
}
Comment vérifier si T est un animal? Je ne veux pas avoir quelque chose qui vérifie pendant l'exécution. Merci
Réponses:
Utilisez
is_same
:Habituellement, c'est une conception totalement irréalisable, cependant, et vous voulez vraiment vous spécialiser :
Notez également qu'il est inhabituel d'avoir des modèles de fonctions avec des arguments explicites (non déduits). Ce n'est pas rare, mais il existe souvent de meilleures approches.
la source
T
n'est pas déduit, vous ne pouvez pas faire grand-chose. Vous pouvez laisser le modèle principal non implémenté et créer une spécialisation, ou vous pouvez ajouter une assertion statique avecis_same
.Je pense qu'aujourd'hui, il vaut mieux l'utiliser, mais uniquement avec C ++ 17.
Si vous utilisez des opérations spécifiques au type dans le corps de l'expression if sans
constexpr
, ce code ne sera pas compilé.la source
std::is_same<T, U>::value
vous pourriez utiliser plus court:std::is_same_v<T, U>
En C ++ 17, nous pouvons utiliser des variantes .
Pour l'utiliser
std::variant
, vous devez inclure l'en-tête:Après cela, vous pouvez ajouter
std::variant
votre code comme ceci:la source
type
qui est la valeur de typeType
ou un modèle qui n'a pas de sens ici)is_same_v
ne sont pas significatives dans le contexte devariant
. Le "trait" correspondant estholds_alternative
.std::variant
est totalement inutile iciVous pouvez spécialiser vos modèles en fonction de ce qui est passé dans leurs paramètres comme ceci:
Notez que cela crée une fonction entièrement nouvelle basée sur le type passé en tant que
T
. Ceci est généralement préférable car cela réduit l'encombrement et c'est essentiellement la raison pour laquelle nous avons des modèles en premier lieu.la source