Почему компилятор сопоставляет "char "с" int", но не"short"?


у меня есть небольшая программа:

#include<iostream>
using namespace std;

void f(int)   { cout << "intn";   }
void f(short) { cout << "shortn"; }

int main(void){
    char c = 0;
    f(c);
    return 0;
}

печати int. Я чувствовал, что, если это из-за" целочисленного продвижения", почему не short предпочтительный?

я также знаю, что целочисленное продвижение происходит в выражении (например, A=B). Но у меня нет выражения в вызове f(), верно?

если это связано с правилом разрешения перегрузки, зачем передавать char to f приведет к компиляторам, предпочитающим int to short?

если Я удаляю f(int), потом f(c) будем называть f(short)!

Итак, мой вопрос в том, связано ли это с" целочисленным продвижением "или просто"правилом разрешения перегрузки"? И почему?

2 67

2 ответа:

(интегральное) продвижение предпочтительнее (интегрального) преобразования по перегрузка разрешение

рейтинг неявное преобразование последовательности

1) точное соответствие: не требуется преобразование, преобразование lvalue в rvalue, преобразование квалификации, преобразование указателя функции, (начиная с C++17) пользовательское преобразование типа класса в тот же класс

2) продвижение: комплексное продвижение, продвижение с плавающей запятой

3) преобразования: интегральное преобразование, преобразование с плавающей запятой, преобразование с плавающей запятой, преобразование указателя, преобразование указателя в член, булево преобразование, пользовательское преобразование производного класса в его базу

Итак, продвижение от char до int предпочтительнее преобразования из char до short.


что такое продвижение? вы можете спросить. Это особый вид преобразования описан стандартом.

почему char до short не пропаганда?, вы можете продолжать. комплексное продвижение всегда int или более крупный тип. Там нет никаких рекламных акций short.

следующие неявные преобразования классифицируются как интегральные акции:

  • signed char или signed short могут быть преобразованы в int;

  • unsigned char или unsigned short могут быть преобразованы в int, если он может содержать весь диапазон значений, а unsigned int в противном случае;

  • char может быть преобразован в int или unsigned int в зависимости от базового типа: signed char или unsigned char (см. выше);

  • wchar_t, char16_t и char32_t могут быть преобразованы в первый тип из следующего списка, способного содержать весь их диапазон значений: int, unsigned инт, неподписанные долго, долго долго долго, неподписанные долго долго; тип перечисления без области видимости, базовый тип которого не является фиксированным, может быть преобразован в первый тип из следующего списка, способного содержать весь диапазон значений: int, unsigned int, long, unsigned long, long long или unsigned long long. Если диапазон значений больше, то интегральные акции не применяются;

  • тип перечисления с незаданной областью, базовый тип которого фиксирован, может быть преобразован в повышенный базовый тип;

    (начиная с C++11)

  • тип битового поля может быть преобразован в int, если он может представлять весь диапазон значений битового поля, в противном случае в unsigned int, если он может представлять весь диапазон значений битового поля, в противном случае не применяются интегральные акции; тип bool может быть преобразован в int со значением false становится 0 и true становится 1.


стандартные ссылки (текущий проект стандарта):

[окончен.микросхема.scs] § 3

[conv.пром] § 1

С неявное преобразование (cppreference):

следующие неявные преобразования классифицируются как интегральные акции:

  • [...]
  • char может быть преобразован в int или unsigned int в зависимости от базового типа: signed char или unsigned char (см. выше);
  • [...]

Итак, если есть функция f(int) и f(short), компилятор будет пытаться сделать Ан продвижение целого числа во-первых, если это невозможно, он будет откат к преобразования целых чисел.

char до int это продвижение целого числа (см. выше), поэтому компилятор выберет его.

если их нет f(int), компилятор не сможет найти функцию, в которой он может выполнять целочисленное продвижение, и вернется к целочисленному преобразованию. Он находит f(short) и char может быть преобразован в short, так что выберу его.