Oui, c'est un paramètre non type. Vous pouvez avoir plusieurs types de paramètres de modèle
- Paramètres de type.
- Les types
- Modèles (uniquement des classes et des modèles d'alias, pas de fonctions ou de modèles de variables)
- Paramètres non types
- Pointeurs
- Références
- Expressions constantes intégrales
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:
template<typename T>
struct Container {
T t;
};
// pass type "long" as argument.
Container<long> test;
Paramètre entier du modèle:
template<unsigned int S>
struct Vector {
unsigned char bytes[S];
};
// pass 3 as argument.
Vector<3> test;
Paramètre de pointeur de modèle (passage d'un pointeur vers une fonction)
template<void (*F)()>
struct FunctionWrapper {
static void call_it() { F(); }
};
// pass address of function do_it as argument.
void do_it() { }
FunctionWrapper<&do_it> test;
Paramètre de référence du modèle (en passant un entier)
template<int &A>
struct SillyExample {
static void do_it() { A = 10; }
};
// pass flag as argument
int flag;
SillyExample<flag> test;
Paramètre de modèle de modèle.
template<template<typename T> class AllocatePolicy>
struct Pool {
void allocate(size_t n) {
int *p = AllocatePolicy<int>::allocate(n);
}
};
// pass the template "allocator" as argument.
template<typename T>
struct allocator { static T * allocate(size_t n) { return 0; } };
Pool<allocator> test;
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:
template<unsigned int SIZE = 3>
struct Vector {
unsigned char buffer[SIZE];
};
Vector<> test;
Syntaxiquement, template<>
est réservé pour marquer une spécialisation de modèle explicite, au lieu d'un modèle sans paramètres:
template<>
struct Vector<3> {
// alternative definition for SIZE == 3
};
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;