Lors de la déclaration d'un template, j'ai l'habitude d'avoir ce genre de code:
template <class T>
Mais dans cette question , ils ont utilisé:
template <unsigned int N>
J'ai vérifié qu'il compile. Mais qu'est-ce que ça veut dire? Est-ce un paramètre non-type? Et si oui, comment pouvons-nous avoir un modèle sans paramètre de type?
static constexpr int
au lieu de votreenum
. Donc, leFactorial<0>
modèle auraitstatic constexpr int value = 1
, ettemplate <int N> struct Factorial
peut avoirstatic constexpr int value = N * Factorial<N - 1>::value;
constexpr
.Oui, c'est un paramètre non type. Vous pouvez avoir plusieurs types de paramètres de modèle
Ce que vous avez là-bas est du dernier genre. C'est une constante de temps de compilation (dite expression constante) et est de type entier ou énumération. Après l'avoir recherché dans la norme, j'ai dû déplacer les modèles de classe vers le haut dans la section des types - même si les modèles ne sont pas des types. Mais ils sont appelés paramètres de type dans le but de décrire néanmoins ces types. Vous pouvez avoir des pointeurs (et aussi des pointeurs membres) et des références à des objets / fonctions qui ont un lien externe (ceux qui peuvent être liés à partir d'autres fichiers objets et dont l'adresse est unique dans tout le programme). Exemples:
Paramètre de type de modèle:
Paramètre entier du modèle:
Paramètre de pointeur de modèle (passage d'un pointeur vers une fonction)
Paramètre de référence du modèle (en passant un entier)
Paramètre de modèle de modèle.
Un modèle sans aucun paramètre n'est pas possible. Mais un modèle sans argument explicite est possible - il a des arguments par défaut:
Syntaxiquement,
template<>
est réservé pour marquer une spécialisation de modèle explicite, au lieu d'un modèle sans paramètres:la source
SillyExample
ne peut pas être compilé par GCC 4.8.4. La première erreur estthe value of ‘flag’ is not usable in a constant expression
. Il y a aussi d'autres erreursVous modélisez votre classe sur la base d'un «int non signé».
Exemple:
la source
Une classe de modèle est comme une macro, mais beaucoup moins maléfique.
Considérez un modèle comme une macro. Les paramètres du modèle sont remplacés dans une définition de classe (ou de fonction) lorsque vous définissez une classe (ou une fonction) à l'aide d'un modèle.
La différence est que les paramètres ont des «types» et que les valeurs passées sont vérifiées lors de la compilation, comme les paramètres des fonctions. Les types valides sont vos types C ++ normaux, comme int et char. Lorsque vous instanciez une classe de modèle, vous transmettez une valeur du type que vous avez spécifié et, dans une nouvelle copie de la définition de classe de modèle, cette valeur est remplacée là où le nom du paramètre se trouvait dans la définition d'origine. Tout comme une macro.
Vous pouvez également utiliser les types "
class
" ou "typename
" pour les paramètres (ils sont vraiment les mêmes). Avec un paramètre de l'un de ces types, vous pouvez passer un nom de type au lieu d'une valeur. Tout comme avant, partout où le nom du paramètre était dans la définition de classe de modèle, dès que vous créez une nouvelle instance, devient le type que vous passez. Il s'agit de l'utilisation la plus courante d'une classe de modèle; Tout le monde qui sait quelque chose sur les modèles C ++ sait comment faire cela.Considérez cet exemple de code de classe de modèle:
C'est fonctionnellement le même que ce code utilisant une macro:
Bien sûr, la version du modèle est un milliard de fois plus sûre et plus flexible.
la source