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

时间:2016-05-11 14:47:15

标签: c++ type-conversion overloading

我有一个小程序:

#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会导致编译器更喜欢intshort

如果我删除f(int),则f(c)会致电f(short)

总而言之,我的问题是,它与“整数推广”还是“重载解析规则”有关?为什么?

2 个答案:

答案 0 :(得分:65)

(积分)促销优先于overload resolution

的其他(整体)转化
  

隐式转换序列的排名

     

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

     

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

     

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

因此,从charint的升级优先于从char转换为short

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

为什么charshort不是促销?,您可以继续。 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.

  •   

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

[over.ics.scs] § 3

[conv.prom] § 1

答案 1 :(得分:22)

来自Implicit conversion(cppreference):

  

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

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

因此,如果有一个函数f(int)f(short),编译器将首先尝试进行整数提升,如果不可能,它将回退到a 整数转换

charint整数提升(见上文),因此编译器会选择它。

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

相关问题