Envoyé par
Nilsou
Oui ben c'est le mécanisme de surcharge quoi ...
Certes mais là ça fait beaucoup de boulot à pas cher.
Par exemple std::floating_point ça ne désigne pas simplement le type float, mais tous les types à virgule flottante donc float, double et long double.
Donc là avec
Code:
template<std::floating_point T>
void foo(T value)
Le compilateur va pouvoir instancier les trois variantes de foo pour ces trois types. Et ne les instanciera réellement que si le code les utilise avec ces types, aucun gâchis.
Après ça reste un usage un peu basique, on peut faire des trucs bien plus avancés notamment avec le mot-clé requires qui permet de filtrer les objets qui peuvent évaluer les expressions de ton choix.
Par exemple tu pourrais définir le concept "possède une opération d'addition et de multiplication"
Code:
template<typename T>
concept HasAddandMul = requires (T a, T b) {
a + b;
a * b;
};
A partir de là, si un objet valide ce concept tu sais qu'il pourra évaluer ces opérations... donc tu peux écrire une fonction 100% générique qui ne se base que sur ces propriétés.
Par exemple un produit scalaire sur des vecteurs
Code:
template<typename T> requires HasAddandMul<T>
T dotProduct(std::vector<T> a, std::vector<T> b) {
...}
(disclaimer : ma syntaxe est peut-être voire probablement pas bonne, c'est pour illustrer l'idée )
Et là tu peux donner absolument n'importe quelle classe à ce dotProduct si elle valide le concept, donc ça marchera avec le types arithmétiques de base mais n'importe quoi d'autre que tu aurais pu définir, des complexes, des quaternions, des entiers astronomique en 437 bits...