J'ai un petit programme:
#include<iostream>
using namespace std;
void f(int) { cout << "int\n"; }
void f(short) { cout << "short\n"; }
int main(void){
char c = 0;
f(c);
return 0;
}
Il affiche int
. J'ai senti que, si c'était à cause de la "promotion entière", pourquoi short
n'était-il pas préféré?
Je sais également que la promotion d'entiers se produit dans une expression (comme A = B). Mais je n'ai pas d'expression dans l'appel à f(),
non?
Si cela est lié à la règle de résolution de surcharge, pourquoi passer char
à f entraînera les compilateurs préférant int
à short
?
Si je supprime f(int)
, alors f(c)
appellera f(short)
!
Donc, en résumé, ma question est la suivante: est-ce lié à la "promotion entière" ou simplement à la "règle de résolution de surcharge"? Et pourquoi?
La promotion (intégrale) est préférée aux autres conversions (intégrales) par résolution de surcharge
Classement des séquences de conversion implicites
1) Correspondance exacte: aucune conversion requise, conversion lvalue en rvalue, conversion de qualification, conversion de pointeur de fonction, (depuis C++ 17) conversion définie par l'utilisateur du type de classe vers la même classe
2) Promotion : promotion intégrale, promotion à virgule flottante
3) Conversion : conversion intégrale, conversion à virgule flottante, conversion intégrale flottante, conversion de pointeur, conversion de pointeur à membre, conversion booléenne, utilisateur- conversion définie d'une classe dérivée vers sa base
Ainsi, la promotion de char
vers int
est préférée à la conversion de char
en short
.
Qu'est-ce que la promotion? vous pouvez demander. Il s'agit d'un type spécial de conversion décrit par la norme.
Pourquoi char
à short
n'est pas une promotion?, vous pouvez continuer. Promotion intégrale est toujours vers int
ou un type plus grand. Il n'y a pas de promotions sur short
.
Les conversions implicites suivantes sont classées comme promotions intégrales:
le caractère signé ou le court signé peut être converti en entier;
un caractère non signé ou un short non signé peut être converti en int s'il peut contenir toute sa plage de valeurs, et unsigned int sinon;
char peut être converti en int ou unsigned int selon le type sous-jacent: char signé ou char non signé (voir ci-dessus);
wchar_t, char16_t et char32_t peuvent être convertis dans le premier type de la liste suivante capable de contenir toute leur plage de valeurs: int, unsigned int, long, unsigned long, long long, unsigned long long; un type d'énumération non étendue dont le type sous-jacent n'est pas fixe peut être converti en le premier type de la liste suivante capable de contenir l'intégralité de leur plage de valeurs: int, unsigned int, long, unsigned long, long long ou unsigned long long. Si la plage de valeurs est supérieure, aucune promotion intégrale ne s'applique;
un type d'énumération non étendue dont le type sous-jacent est fixe peut être converti en son type sous-jacent promu;
(depuis C++ 11)
un type de champ de bits peut être converti en int s'il peut représenter toute la plage de valeurs du champ de bits, sinon en entier non signé s'il peut représenter toute la plage de valeurs du champ de bits, sinon aucune promotion intégrale ne s'applique; le type bool peut être converti en int avec la valeur false devenant 0 et true devenant 1.
Références standard (version standard actuelle):
De conversion implicite (cppreference):
Les conversions implicites suivantes sont classées comme promotions intégrales:
- [...]
char
peut être converti enint
ouunsigned int
selon le type sous-jacent:signed char
ouunsigned char
(voir ci-dessus);- [...]
Donc, s'il y a une fonction f(int)
et f(short)
, le compilateur essaiera de faire un promotion entière d’abord, s’il n’est pas possible, il reviendra à un conversion d'entier.
char
à int
est un promotion entière (voir ci-dessus), donc le compilateur le choisira.
S'il n'y a pas de f(int)
, le compilateur ne trouvera pas de fonction où il peut faire la promotion d'entiers et se repliera sur la conversion d'entiers. Il trouve une f(short)
, et un char
peut être converti en short
, donc il le choisira.