为什么编译器将 "char" 匹配到 "int" 而不是 "short"?
Why does the compiler match "char" to "int" but not "short"?
我有一个小程序:
#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
。我觉得,如果这是因为 "Integer promotion",为什么 short
不是首选?
我也知道整数提升发生在表达式中(如 A=B)。但是我在调用 f(),
时没有表达,对吗?
如果这与重载决议规则有关,为什么将 char
传递给 f 会导致编译器更喜欢 int
而不是 short
?
如果我删除 f(int)
,那么 f(c)
将调用 f(short)
!
总而言之,我的问题是,它与 "Integer promotion" 相关还是仅与 "overload resolution rule" 相关?为什么?
来自 Implicit conversion(cppreference):
The following implicit conversions are classified as integral promotions:
- [...]
char
can be converted to int
or unsigned int
depending on the underlying type: signed char
or unsigned char
(see above);
- [...]
因此,如果存在函数 f(int)
和 f(short)
,编译器将首先尝试执行 整数提升 ,如果不可能的话, 它将回退到 整数转换 .
char
到int
是一个整数提升(见上文),所以编译器会选择它。
如果没有任何 f(int)
,编译器将无法找到可以进行整数提升的函数,并将回退到整数转换。它找到一个f(short)
,一个char
可以转换成一个short
,所以它会选择
(积分)促销优于其他(积分)转化 overload resolution
Ranking of implicit conversion sequences
1) Exact match: no conversion required, lvalue-to-rvalue conversion, qualification conversion, function pointer conversion, (since C++17) user-defined conversion of class type to the same class
2) Promotion: integral promotion, floating-point promotion
3) Conversion: integral conversion, floating-point conversion, floating-integral conversion, pointer conversion, pointer-to-member conversion, boolean conversion, user-defined conversion of a derived class to its base
因此,从 char
到 int
的提升优于从 char
到 short
的转换。
什么是推广?你可能会问。它是标准描述的一种特殊类型的转换。
为什么char
到short
不是促销?,你可以继续。 Integral promotion 总是 int
或更大的类型。 short
.
没有晋升
The following implicit conversions are classified as integral promotions:
signed char or signed short can be converted to int;
unsigned char or unsigned short can be converted to int if it can hold its entire value range, and unsigned int otherwise;
char can be converted to int or unsigned int depending on the underlying type: signed char or unsigned char (see above);
wchar_t, char16_t, and char32_t can be converted to the first type from the following list able to hold their entire value range: int, unsigned int, long, unsigned long, long long, unsigned long long;
an unscoped enumeration type whose underlying type is not fixed can be converted to the first type from the following list able to hold their entire value range: int, unsigned int, long, unsigned long, long long, or unsigned long long. If the value range is greater, no integral promotions apply;
an unscoped enumeration type whose underlying type is fixed can be converted to its promoted underlying type;
(since C++11)
a bit field type can be converted to int if it can represent entire value range of the bit field, otherwise to unsigned int if it can represent entire value range of the bit field, otherwise no integral promotions apply;
the type bool can be converted to int with the value false becoming 0 and true becoming 1.
标准参考(当前标准草案):
我有一个小程序:
#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
。我觉得,如果这是因为 "Integer promotion",为什么 short
不是首选?
我也知道整数提升发生在表达式中(如 A=B)。但是我在调用 f(),
时没有表达,对吗?
如果这与重载决议规则有关,为什么将 char
传递给 f 会导致编译器更喜欢 int
而不是 short
?
如果我删除 f(int)
,那么 f(c)
将调用 f(short)
!
总而言之,我的问题是,它与 "Integer promotion" 相关还是仅与 "overload resolution rule" 相关?为什么?
来自 Implicit conversion(cppreference):
The following implicit conversions are classified as integral promotions:
- [...]
char
can be converted toint
orunsigned int
depending on the underlying type:signed char
orunsigned char
(see above);- [...]
因此,如果存在函数 f(int)
和 f(short)
,编译器将首先尝试执行 整数提升 ,如果不可能的话, 它将回退到 整数转换 .
char
到int
是一个整数提升(见上文),所以编译器会选择它。
如果没有任何 f(int)
,编译器将无法找到可以进行整数提升的函数,并将回退到整数转换。它找到一个f(short)
,一个char
可以转换成一个short
,所以它会选择
(积分)促销优于其他(积分)转化 overload resolution
Ranking of implicit conversion sequences
1) Exact match: no conversion required, lvalue-to-rvalue conversion, qualification conversion, function pointer conversion, (since C++17) user-defined conversion of class type to the same class
2) Promotion: integral promotion, floating-point promotion
3) Conversion: integral conversion, floating-point conversion, floating-integral conversion, pointer conversion, pointer-to-member conversion, boolean conversion, user-defined conversion of a derived class to its base
因此,从 char
到 int
的提升优于从 char
到 short
的转换。
什么是推广?你可能会问。它是标准描述的一种特殊类型的转换。
为什么char
到short
不是促销?,你可以继续。 Integral promotion 总是 int
或更大的类型。 short
.
The following implicit conversions are classified as integral promotions:
signed char or signed short can be converted to int;
unsigned char or unsigned short can be converted to int if it can hold its entire value range, and unsigned int otherwise;
char can be converted to int or unsigned int depending on the underlying type: signed char or unsigned char (see above);
wchar_t, char16_t, and char32_t can be converted to the first type from the following list able to hold their entire value range: int, unsigned int, long, unsigned long, long long, unsigned long long; an unscoped enumeration type whose underlying type is not fixed can be converted to the first type from the following list able to hold their entire value range: int, unsigned int, long, unsigned long, long long, or unsigned long long. If the value range is greater, no integral promotions apply;
an unscoped enumeration type whose underlying type is fixed can be converted to its promoted underlying type;
(since C++11)
a bit field type can be converted to int if it can represent entire value range of the bit field, otherwise to unsigned int if it can represent entire value range of the bit field, otherwise no integral promotions apply; the type bool can be converted to int with the value false becoming 0 and true becoming 1.
标准参考(当前标准草案):