一般算术转换
来自cppreference.com
许多期待具有算术类型或枚举类型的操作数的二元运算符会以相似的方法进行转换并产生结果类型。这样做的目的是产生公共类型,也就是结果类型。该范式被称为一般算术转换 。
定义
一般算数转换定义如下:
阶段 1
|
(C++11 起) |
阶段 2
|
(C++23 前) |
|
(C++23 起) |
阶段 3
将两个操作数都转换到公共类型 C
。给定类型 T1
和 T2
为两个操作数的(在整数提升规则下的)提升后类型,应用以下规则确定 C
:
- 如果
T1
和T2
是相同类型,那么C
是该类型。 - 否则,如果
T1
和T2
都是有符号整数类型或者都是无符号整数类型,那么C
是具有更高整数转换等级的类型。 - 否则,
T1
和T2
之中的一个类型是有符号整数类型S
,而另一个类型是无符号整数类型U
。应用以下规则:
- 如果
U
的整数转换等级高于或等于S
的整数转换等级,那么C
是U
。 - 否则,如果
S
可以表示U
的所有值,那么C
是S
。 - 否则,
C
是与S
对应的无符号整数类型。
- 如果
如果一个操作数具有枚举类型,而另一个操作数具有另一个枚举类型或浮点类型,那么行为被弃用。 |
(C++20 起) |
整数转换等级
每个整数类型都有一个整数转换等级,定义如下:
- 除了 char 和 signed char(如果 char 有符号)以外的所有有符号整数类型的等级都不相同,即使它们的表示相同。
- 对于两个有符号整数类型,宽度更小的类型的等级低于宽度更大的类型的等级。
- 以下整数类型的等级递减:
|
(C++11 起) |
- long
- int
- short
- signed char
- 每个无符号整数类型的等级都等于对应的有符号整数类型的等级。
- 每个标准整数类型的等级都高于具有相同宽度的扩展整数类型的等级。
- char、signed char 和 unsigned char 具有相同等级。
- bool 的等级低于所有标准整数类型的等级。
- char8_t、 (C++20 起)char16_t、char32_t 和 (C++11 起) wchar_t 的等级等于它们对应底层类型的等级,也就是说:
|
(C++20 起) |
|
(C++11 起) |
- wchar_t 的等级等于它的由实现定义的底层类型的等级。
- 两个扩展有符号整数类型的等级的高低由实现定义,但不能违背确定整数转换等级的其他规则。
- 对于所有整数类型
T1
、T2
和T3
,如果T1
的等级高于T2
的等级,并且T2
的等级高于T3
的等级,那么T1
的等级高于T3
的等级。
整数转换等级也用于定义整数提升。
浮点转换等级与子等级浮点转换等级每个浮点类型都有一个浮点转换等级,定义如下:
浮点转换子等级浮点转换等级相等的浮点类型按浮点转换子等级 有序。该子等级在所有等级相等的类型中组成全序。
用途浮点转换等级和子等级也用于:
|
(C++23 起) |
缺陷报告
下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。
缺陷报告 | 应用于 | 出版时的行为 | 正确行为 |
---|---|---|---|
CWG 2528 | C++20 | unsigned char 和 unsigned int 之间 的三路比较因为中途的整数提升而非良构[1] |
在实际没有进行整数提升的情况下 根据提升后类型确定公共类型[2] |