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

Why does the compiler match "char" to "int" but not "short"?

本文关键字:short int 编译器 char 为什么      更新时间:2023-10-16

我有一个小程序:

#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传递给f会导致编译器更喜欢int而不是short

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

所以综上所述,我的问题是,它是否与"整数提升"或只是"过载解析规则"有关?为什么呢?

(积分( 通过重载分辨率,提升优先于其他(积分(转换

隐式转换序列的排名

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

2(推广:积分提升、浮点推广

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

因此,从charint的晋升比从charshort的转换更可取。


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

为什么char short不是晋升?,你可以继续。整体晋升始终是针对int或更大的类型。没有促销活动short

以下隐式转换被归类为积分促销:

    有符号
  • 字符或有符号短字符可以转换为 int;

  • 如果无符号字符
  • 或无符号短字符可以保存其整个值范围,则可以转换为 int,否则可以转换为无符号 int;

  • char 可以转换为 int 或无符号 int,具体取决于
  • 底层类型:有符号 char 或无符号 char(见上文(;

  • wchar_t、char16_t 和 char32_t 可以转换为以下列表中能够保存其整个值范围的第一种类型:int、无符号 int、long、无符号 long、long long、无符号 long long; 基础类型不固定的无作用域枚举类型可以转换为以下列表中的第一个类型,该类型能够保存其整个值范围:int、无符号整数、长整型、无符号长整型、长整型或无符号长整型。如果价值范围更大,则不适用积分促销;

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

    (自C++11起(

  • 如果位字段类型可以表示位字段的整个
  • 值范围,则可以将其转换为 int,如果它可以表示位字段的整个值范围,则可以将其转换为无符号 int,否则不适用整数提升; 布尔类型可以转换为 int,值 false 变为 0,true 变为 1。


标准

参考(当前标准草案(:

[上.ics.scs] § 3

[会议舞会] § 1

来自隐式转换(cpp首选项(:

以下隐式转换被归类为积分促销:

  • [...]
  • char可以根据基础类型转换为intunsigned intsigned charunsigned char(见上文(;
  • [...]

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

char int是一个整数提升(见上文(,因此编译器会选择它。

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