为什么编译器将"char"与"int"匹配而不是"short"?

Hin*_*sum 69 c++ overloading type-conversion

我有一个小程序:

#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;
}
Run Code Online (Sandbox Code Playgroud)

它打印int.我觉得,如果这是因为"整体推广",为什么不short首选?

我也知道整数提升发生在表达式中(如A = B).但是我没有接到电话中的表情f(),吗?

如果这是重载解决规则有关,为什么传递char到F将导致到编译器宁愿intshort

如果我删除f(int),那么f(c)会打电话f(short)!

总而言之,我的问题是,它是与"整数提升"还是仅仅是"超载解决规则"有关?为什么?

eer*_*ika 65

(积分)通过重载决策,促销优先于其他(整体)转换

隐式转换序列的排名

1)完全匹配:不需要转换,左值到右值转换,限定转换,函数指针转换,(从C++ 17开始)用户定义的类类型转换为同一类

2)推广:整体推广,浮点推广

3)转换:积分转换,浮点转换,浮点积分转换,指针转换,指针到成员转换,布尔转换,派生类到其基数的用户定义转换

因此,从促进charint由优于转换charshort.


什么是促销?你可能会问.这是标准描述的一种特殊转换.

为什么charshort不升职?,你可以继续.整体推广总是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,long,unsigned long,long long,unsigned long long; 无作用域枚举类型,其基础类型是不固定的可以从以下列表中能够保持它们的整个值的范围被转换为所述第一类型:整数,无符号整型,长,无符号长,长长,或无符号长长.如果价值范围较大,则不适用整体促销;

  • 其基础类型固定的无范围枚举类型可以转换为其提升的基础类型;

    (自C++ 11以来)

  • 如果位字段类型可以表示位字段的整个值范围,则可以将其转换为int,否则如果它可以表示位字段的整个值范围,则转换为unsigned int,否则不应用整数提升; bool类型可以转换为int,值false为0,true为1.


标准参考(当前标准草案):

[over.ics.scs]§3

[conv.prom]§1


Rak*_*111 22

来自隐式转换(cppreference):

以下隐式转化被归类为整体促销:

  • [...]
  • char可以转换为intunsigned int取决于基础类型:signed charunsigned char(见上文);
  • [...]

所以,如果有一个函数f(int)f(short),编译器会尝试做一个整数的推广首先,如果它是不可能的,它会退回到一个整数转换.

charto int整数提升(见上文),因此编译器会选择它.

如果没有f(int),编译器将无法找到可以进行整数提升的函数,并且将回退到整数转换.它找到一个f(short),并且char可以转换成一个short,所以它会选择它.