c++ - tuto - ¿Por qué el compilador hace coincidir "char" con "int" pero no "short"?
try on c++ (2)
Tengo un pequeño programa:
#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;
}
Imprime
int
.
Sentí que, si esto se debe a la "Promoción de enteros", ¿por qué no se prefiere
short
?
También sé que la promoción de enteros ocurre en una expresión (como A = B).
Pero no tengo expresión en la llamada a
f(),
¿verdad?
Si esto está relacionado con la regla de resolución de sobrecarga, ¿por qué pasar
char
a f dará como resultado que los compiladores prefieran
int
a
short
?
Si elimino
f(int)
, entonces
f(c)
llamará a
f(short)
.
En resumen, mi pregunta es, ¿está relacionado con la "Promoción de enteros" o simplemente con la "regla de resolución de sobrecarga"? ¿Y por qué?
De la conversión implícita (cppreference):
Las siguientes conversiones implícitas se clasifican como promociones integrales:
- [...]
char
se puede convertir aint
ounsigned int
dependiendo del tipo subyacente :signed char
ounsigned char
(ver arriba);- [...]
Por lo tanto, si hay una función
f(int)
f(short)
, el compilador intentará hacer una
promoción entera
primero, si no es posible, recurrirá a una
conversión entera
.
char
to
int
es una
promoción entera
(ver arriba), por lo que el compilador la elegirá.
Si no hay ninguna
f(int)
, el compilador no podrá encontrar una función donde pueda hacer una promoción de enteros y recurrirá a la conversión de enteros.
Encuentra un
f(short)
, y un
char
puede convertirse en un
short
, por lo que lo elegirá.
La promoción (integral) se prefiere a otras conversiones (integrales) por resolución de sobrecarga
Clasificación de secuencias de conversión implícitas
1) Concordancia exacta: no se requiere conversión, conversión lvalue-to-rvalue, conversión de calificación, conversión de puntero de función, (desde C ++ 17) conversión definida por el usuario del tipo de clase a la misma clase
2) Promoción : promoción integral, promoción de punto flotante
3) Conversión : conversión integral, conversión de punto flotante, conversión integral flotante, conversión de puntero, conversión de puntero a miembro, conversión booleana, conversión definida por el usuario de una clase derivada a su base
Por lo tanto, la promoción de
char
a
int
es preferible a la conversión de
char
a
short
.
¿Qué es la promoción? Tu puedes preguntar. Es un tipo especial de conversión descrito por el estándar.
¿Por qué
char
a
short
no es una promoción?
, puedes continuar.
La promoción integral
es siempre a
int
o un tipo más grande.
No hay promociones para
short
.
Las siguientes conversiones implícitas se clasifican como promociones integrales:
El char firmado o el short firmado se pueden convertir a int;
unsigned char o unsigned short se pueden convertir a int si puede mantener todo su rango de valores, y unsigned int de lo contrario;
char se puede convertir a int o unsigned int dependiendo del tipo subyacente :igned char o unsigned char (ver arriba);
wchar_t, char16_t y char32_t se pueden convertir al primer tipo de la siguiente lista capaz de contener todo su rango de valores: int, unsigned int, long, unsigned long, long long, unsigned long long; un tipo de enumeración sin ámbito cuyo tipo subyacente no es fijo se puede convertir al primer tipo de la siguiente lista capaz de mantener su rango de valores completo: int, unsigned int, long, unsigned long, long long o unsigned long long. Si el rango de valores es mayor, no se aplican promociones integrales;
un tipo de enumeración sin ámbito cuyo tipo subyacente es fijo se puede convertir a su tipo subyacente promovido;
(desde C ++ 11)
un tipo de campo de bits se puede convertir a int si puede representar el rango de valores completo del campo de bits, de lo contrario a int sin signo si puede representar el rango de valores completo del campo de bits, de lo contrario no se aplican promociones integrales; el tipo bool se puede convertir a int con el valor falso convirtiéndose en 0 y verdadero convirtiéndose en 1.
Referencias estándar (borrador estándar actual):