我有一个小程序:
#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;
}
打印int
。我觉得,如果这是因为“整体推广”,为什么short
不是首选?
我也知道整数提升发生在表达式中(如A = B)。但我没有表达对f(),
的呼吁吗?
如果这与重载解析规则有关,为什么将char
传递给f会导致编译器更喜欢int
到short
?
如果我删除f(int)
,则f(c)
会致电f(short)
!
总而言之,我的问题是,它与“整数推广”还是“重载解析规则”有关?为什么?
答案 0 :(得分:65)
(积分)促销优先于overload resolution
的其他(整体)转化隐式转换序列的排名
1)完全匹配:不需要转换,左值到右值转换,限定转换,函数指针转换,(自C ++ 17开始)用户定义的类类型转换为同一类
2)促销:整体推广,浮点促销
3)转换:积分转换,浮点转换,浮点积分转换,指针转换,指针到成员转换,布尔转换,派生类到用户定义的转换基
因此,从char
到int
的升级优先于从char
转换为short
。
什么是促销?你可能会问。这是标准描述的一种特殊转换。
为什么char
到short
不是促销?,您可以继续。 Integral promotion总是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; 其基础类型未修复的未作用域枚举类型可以转换为以下列表中的第一个类型,该列表能够保存其整个值范围:int,unsigned int,long,unsigned long,long long或unsigned long long。如果价值范围较大,则不适用整体促销;
其基础类型固定的无范围枚举类型可以转换为其提升的基础类型;
(自C ++ 11起)
如果位字段类型可以表示位字段的整个值范围,则可以转换为int,否则如果它可以表示位字段的整个值范围,则转换为unsigned int,否则不应用整数提升; bool类型可以转换为int,值false为0,true为1.
标准参考(当前标准草案):
答案 1 :(得分:22)
来自Implicit conversion(cppreference):
以下隐式转化归类为整体促销:
- [...]
char
可以转换为int
或unsigned int
,具体取决于基础类型:signed char
或unsigned char
(见上文);- [...]
因此,如果有一个函数f(int)
和f(short)
,编译器将首先尝试进行整数提升,如果不可能,它将回退到a 整数转换。
char
到int
是整数提升(见上文),因此编译器会选择它。
如果没有f(int)
,编译器将无法找到可以进行整数提升的函数,并且将回退到整数转换。它找到f(short)
,char
可以转换为short
,因此会选择它。