Chapitre 23 : patron de fonction, de classe, (template)

Patron de fonction

Un patron de fonction est introduit avec le mot clé template. Il admet des paramètres "spéciaux" (entre "<" et ">") qui doivent être associés à des arguments connus à la compilation. Notament il accepte des expressions de type (avec typename).

C'est uniquement lors de l'utilisation d'un patron de fonction que du code machine est produit, c'est pourquoi on le place souvent dans un fichier hpp.

EXEMPLE
template <typename T> int superieur(T a, T b){
  if (a > b){
    return 1;
  }
  else{
    return 0;
  }
}

int c = superieurA<int>(3, 2);
int c = superieurA<double>(3.5, 2);

class A{
  int a;
};

A ob1;
A ob2;

//int d = superieurA<A>(ob1,ob2); //erreur

Remarque

On peut utiliser des argument de type valeur

EXEMPLE
template <int c> int f(int a){...}


f<3>(5); //ok
int c = ...;
//f<c>(5) // risque d'erreur de compilation

Inférence de type

Le compilateur peut déduire les types paramétrés.

EXEMPLE
template <typename T, typename G> void g(T a,G b){...}

void g(int, int){...} //gii

int main(){
  g(3,5.3); //g<int, double>(3,5,3)
  g(3,5) //gii
  g<int,int>(3, 5) //template

Remarque

Comme paramètres spécial, on peut utiliser par exemple

Const expr

On peut déclarer une fonction comme const exp2.

Cela autorise le compilateur à l'executer lors de la compilation.

const expr int f(...){...}
template <int c> g(...){...}

g<f(75)>(...); //ok f(75) est calculé lors de la compilation.

Patron de classe

On peut également construire et utiliser des patrons de classe.

L'inférence de type est effectuée à partir des appels aux méthodes static (dont font partie les constructeurs). Les "instances" de patrons sont construit lors de la compilation.

template <typename T> class A{
  int a = 0;
  T b;
  public:
    void f(){...}
    int g(T c);
    A (T p) : b{p}{}
};

template <typename T> A<T>::g(T c){...}

int main(){
  A<int> obj{3};
  obj.f();
  A obj{3.5}; // A <double> obj{3.5}
}

Alias de type (using)

On peut utiliser using pour créer des alias de type.

EXEMPLE
using k = int*;
using G = A<k>;
template <typename A> using ptr = A*;

k c; //int* c;
G u; //A<int*> u;
ptr<int> c; //int*