126 votes

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

Supposons que j'ai une fonction modèle et deux classes

class animal {
}
class person {
}

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

Comment faire le contrôle pour T est un animal ? Je ne veux pas avoir quelque chose qui vérifie pendant l'exécution. Merci

164voto

Kerrek SB Points 194696

Utilisez is_same :

#include <type_traits>

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

En général, c'est une conception totalement irréalisable, et vous voulez vraiment se 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 fonctions avec des arguments explicites (non cultivés). Ce n'est pas inédit, mais il existe souvent de meilleures approches.

51voto

Je pense qu'aujourd'hui, il est préférable de l'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 de type dans le corps de l'expression if sans constexpr ce code ne sera pas compilé.

7voto

template boy Points 2313

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 qui est passé en tant que T . C'est généralement préférable, car cela réduit le désordre et c'est essentiellement la raison pour laquelle nous avons des modèles en premier lieu.

7voto

scai Points 5123

std::is_same() n'est disponible que depuis C++11. Pour les versions antérieures à C++11, vous pouvez utiliser typeid() :

template <typename T>
void foo()
{
    if (typeid(T) == typeid(animal)) { /* ... */ }
}

6voto

Edwin Pratt Points 403

En C++17, nous pouvons utiliser variantes .

Pour 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...
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X