Surcharge et conversions implicites
Lorsqu’un appel de fonction ne correspond pas exactement à une signature, le compilateur C++ effectue des conversions implicites pour tenter de trouver une correspondance. Ce mécanisme est au coeur de la résolution de surcharge (overload resolution).
Les 3 rangs de conversion #
Le compilateur C++ classe les conversions implicites en 3 rangs, du plus prioritaire au moins prioritaire :
| Rang | Nom | Exemples |
|---|---|---|
| 1 | Exact match | Aucune conversion, ajout de const, lvalue-to-rvalue |
| 2 | Promotion | float → double, short → int, char → int |
| 3 | Conversion | double → int, double → float, int → float |
Exemple concret #
Considérons deux surcharges :
int minimum(int val1, int val2);
float minimum(float val1, float val2);Avec minimum(7, 3)
Le compilateur trouve un exact match (rang 1) pour la version int, et une conversion de rang 3 pour la version float (promotion de int à float), donc il choisit la version int.
Avec minimum(7.0f, 3.0f)
7.0 est de type double, pas float. Pour un littéral float, il faut écrire 7.0f.Le compilateur trouve un exact match (rang 1) pour la version float, et une conversion de rang 3 pour la version int (conversion de float à int), donc il choisit la version float.
Asymétrie float / double
La conversion entre float et double n’est pas symétrique.
float→doubleest une promotion (rang 2)double→floatest une conversion (rang 3)
Avec minimum(7.0, 3.0)
Le compilateur trouve une conversion de rang 3 pour la version int (conversion de double à int), et une conversion de rang 3 pour la version float (conversion de double à float), donc il ne peut pas choisir entre les deux → erreur d’ambiguïté.
Avec minimum(7.0, 3)
Le compilateur trouve une conversion de rang 3 pour la version int (conversion de double à int), et une conversion de rang 3 pour la version float (conversion de double à float + promotion de int à float), donc il ne peut pas choisir entre les deux → erreur d’ambiguïté.