On peut paramétrer ce patron par un type, mais aussi par d'autres arguments :
Exemple:
template<class T, int sz, void (*err)()> class Table{ T tab[sz]; public: T& operator[](int i){ if(i>=sz || i<0)err(); return tab[i]; } T operator[](int i)const{ if(i>=sz || i<0)err(); return tab[i]; } //... };définit un patron de classe, dont le premier paramètre est un type
Un objet de la classe peut être défini suivant ce patron :
void f(){ cerr<<"erreur d'indice\n"; // traiter l'erreur ... } void main(){ typedef Table<int,5,f> T5; T5 t0; T5 t1; Table<T5,10,f> tab; Table<int,5,f> tt[12],*pt; for(int i=0;i<5;i++){ t0[i]=i;t1[i]=i*i; } tab[0]=tab[3]=t0; tab[1]=tab[4]=t1; }
Pour l'instanciation, les paramètres
fournis doivent être des constantes (évaluables à la
compilation). Le nom du type Table<int,5,f>
, par
exemple, est considéré comme un nom de type et peut donc
être utilisé partout où un nom de type peut l'être. Par
contre, le patron n'est pas un type et on ne pourrait pas
avoir :
template <class A> TA{ //... }; class B{ //... TA m; // non }; template <class A> TB{ //... TA<A> m; // ok };