Fonctions génériques

 
template <class T>        T  Min1 (const T  a, const T  b) { return (a < b) ? a : b; } 
template <class T>        T  Min2 (const T& a, const T& b) { return (a < b) ? a : b; } 
template <class T>  const T& Min3 (const T& a, const T& b) { return (a < b) ? a : b; } 

    1) - L'avantage de Min2() par rapport à Min1() est qu'elle utilise un passage par référence des paramètres, donc ne nécessite pas de recopier les objets a et b dans la pile d'exécution, ce qui peut être coûteux en temps et en espace mémoire si le type T est volumineux.

    2) - Min3() passe la valeur de retour (soit a soit b) par référence, donc ne nécessite pas la création d'un objet intermédiaire. Il n'est donc pas necessaire que la classe T ait un constructeur par recopie.

    3) - comme les paramètres formels (à la déclaration) a et b sont passés par référence, et qu'ils sont déclarés const, les paramètres effectifs (à l'appel) peuvent être des constantes. Il ne faudrait pas que la fonction Min3() renvoie une référence à un objet, qui pourrait être alors modifié, comme dans l'exemple ci-dessous :
 
template <class T>  T& Min3 (const T& a, const T& b) { return (a < b) ? a : b; } 

min (3, 4) = 5;
cout << 3 << endl;   // pourrait afficher 5 !!!!!!!

    La constante 3, dont la référence serait renvoyée par Min3(), recevrait alors la valeur 5, ce qui serait assez gênant !!!

    Heureusement, un bon compilateur interdit la défnition ci-dessus de la fonction Min3() si const n'est pas placé devant le type de retour.

      4) - La classe T doit posséder l'opérateur de comparaison <.

      5) -
 
template <class T>  const T& Min3 (const T& a, const T& b) { return (a < b) ? a : b; } 

      6) - Les trois fonctions doivent avoir des identificateurs différents. En effet, le type de retour ne suffit pas à distinguer deux surcharges d'une même fonction, et l'appel d'une fonction dans laquelle les paramètres sont passés par référence ne se distingue pas de celui dans lequel ils sont passés par valeur. Par exemple :
 
 
int a = 3;
int b = 4;
cout << min (a, b); // a et b passés par valeur ou par référence ?

    Donc il y  ambiguïté à la compilation.
 

Fonctions génériques (suite)

    1) -
 
// attention : ne vérifie pas qu'il y a au moins 1 élément !!!

template <class T> const T & MinVect (const vector <T> & V)
{
    unsigned Min = V.size() - 1;
    for (unsigned i = V.size(); i--; ) if (V [i] < V [Min]) Min = i;

    // ou    

    // for (unsigned i = V.size() - 1; i--; ) if (V [i] < V [Min]) Min = i;

    return V [Min];

} // MinVect()

    2) - Cette fonction peut s'appeler min(), car elle n'a pas le même profil que la fonction min() standard.