web-dev-qa-db-fra.com

Comment vérifier le type d'un paramètre de modèle?

Supposons que j'ai une fonction template et deux classes

class animal {
}
class person {
}

template<class T>
void foo() {
  if (T is animal) {
    kill();
  }
}

Comment faire le chèque pour T is animal? Je ne veux pas avoir quelque chose qui vérifie pendant le temps d'exécution. Merci

60

Utilisation is_same:

#include <type_traits>

template <typename T>
void foo()
{
    if (std::is_same<T, animal>::value) { /* ... */ }  // optimizable...
}

Habituellement, c'est une conception totalement irréalisable, cependant, et vous voulez vraiment spécialiser:

template <typename T> void foo() { /* generic implementation  */ }

template <> void foo<animal>()   { /* specific for T = animal */ }

Notez également qu’il est inhabituel d’avoir des modèles de fonction avec des arguments explicites (non déduits). Ce n'est pas du jamais vu, mais il y a souvent de meilleures approches.

87
Kerrek SB

Je pense qu'aujourd'hui, il est préférable d'utiliser, mais seulement avec C++ 17.

#include <type_traits>

template <typename T>
void foo() {
    if constexpr (std::is_same_v<T, animal>) {
        // use type specific operations... 
    } 
}

Si vous utilisez des opérations spécifiques au type dans if expression body sans constexpr, ce code ne sera pas compilé.

En C++ 17, nous pouvons utiliser variantes .

Utiliser std::variant, vous devez inclure l'en-tête:

#include <variant>

Après cela, vous pouvez ajouter std::variant dans votre code comme ceci:

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...
    }
}
6
Edwin Pratt

Vous pouvez spécialiser vos modèles en fonction de ce qui est passé dans leurs paramètres, comme ceci:

template <> void foo<animal> {

}

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 est essentiellement la raison pour laquelle nous avons des modèles en premier lieu.

5
template boy