2017-08-19 3 views
5

Tenir compte de ce programme:Pourquoi la surcharge de fonction prend un int préféré à celui qui prend un caractère non signé?

#include <iostream> 

using namespace std; 

void f(unsigned char c) { 
    cout << c << endl; 
} 

void f(int c) { 
    cout << c << endl; 
} 

int main() { 
    f('a'); 
} 

Cette imprime 97, ce qui suggère que la surcharge f() qui a été choisi est celui qui prend un int. Je trouve ça bizarre; ne serait pas intuitivement un unsigned char être un meilleur match pour un char?

+2

c'est parce que sur votre compilateur char == char signé – Sopel

+0

Je ne peux pas trouver un doublon approprié, mais il y en a probablement un. ce que vous cherchez, c'est comment les séquences de conversion sont gérées. –

+3

Ceci est similaire et devrait aider à expliquer les choses. https://stackoverflow.com/questions/37166131/why-does-the-compiler-match-char-to-int-but-not-short –

Répondre

8

ne serait pas intuitivement un unsigned char être un meilleur match pour un char?

Eh bien, je suppose, mais pas selon la norme. Selon [conv.prom]p1:

A prvalue d'un type entier autre que bool, char16_­t, char32_­t ou wchar_­t dont le rang conversion entier est inférieur au rang d'int peut être converti en un prvalue de type int si int peut représenter toutes les valeurs du type source; [...]

Maintenant, les trois types de caractères ont le même rang, et un type signé a toujours un rang inférieur à int. Ceci est une combinaison de [conv.rank]p1.6 et [conv.rank]p1.2:

  • Le rang d'un type entier signé doit être supérieur au rang de tout type d'entier signé avec une taille plus petite.

  • [...]

  • Le rang de char est égal au rang de signed char et unsigned char.

Fondamentalement, chaque personnage a toujours un petit rang que int et ils peuvent tous être représentés dans un int, et donc la surcharge avec unsigned char n'est pas une meilleure adéquation, car il impliquerait une conversion de char à unsigned char, au lieu d'une promotion.

Si vous changez votre surcharge pour prendre un char, alors il y aurait une correspondance exacte, et donc naturellement, la surcharge "correcte" (dans vos yeux) serait choisie.

+1

Il y a aussi une bonne référence [ici] (http: // fr. cppreference.com/w/cpp/language/overload_resolution), section * "Classement des séquences de conversion implicites" *. Il dit essentiellement que la promotion entière/à virgule flottante est préférée à la conversion. – HolyBlackCat