常用算术转换
来自 cppreference.cn
许多期望算术或枚举类型操作数的二元运算符,以类似的方式引起转换并产生结果类型。目的是产生一个通用类型,这也是结果的类型。这种模式称为常用算术转换。
目录 |
[编辑] 定义
常用算术转换定义如下
[编辑] 阶段 1
对两个操作数应用左值到右值转换,生成的纯右值将代替原始操作数用于剩余过程。
[编辑] 阶段 2
|
(自 C++11 起) |
[编辑] 阶段 3
|
(自 C++26 起) |
[编辑] 阶段 4
- 如果任一操作数是浮点类型,则应用以下规则
- 如果两个操作数具有相同的类型,则不执行进一步的转换。
- 否则,如果其中一个操作数是非浮点类型,则将该操作数转换为另一个操作数的类型。
- 否则,如果操作数类型的浮点转换等级已排序但(自 C++23 起)不相等,则将浮点转换等级较低的类型的操作数转换为另一个操作数的类型。
|
(自 C++23 起) |
- 否则,两个操作数都是整数类型,进行到下一阶段。
[编辑] 阶段 5
两个操作数都转换为通用类型 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 起) (直到 C++26) |
[编辑] 整数转换等级
每个整数类型都有一个整数转换等级,定义如下
- 除了 char 和 signed char (如果 char 是有符号的) 之外,即使两个有符号整数类型具有相同的表示形式,它们也不具有相同的等级。
- 有符号整数类型的等级大于任何宽度较小的有符号整数类型的等级。
- 以下整数类型的等级按顺序递减
|
(自 C++11 起) |
- long
- int
- short
- signed char
- 任何无符号整数类型的等级等于相应有符号整数类型的等级。
|
(自 C++11 起) |
- bool 的等级小于所有标准整数类型的等级。
- 编码字符类型 (char , char8_t(自 C++20 起), char16_t, char32_t,(自 C++11 起) 和 wchar_t) 的等级等于其底层类型的等级,这意味着
- char 的等级等于 signed char 和 unsigned char 的等级。
|
(自 C++20 起) |
|
(自 C++11 起) |
- wchar_t 的等级等于其实例定义的底层类型的等级。
|
(自 C++11 起) |
- 对于所有整数类型
T1
、T2
和T3
,如果T1
的等级大于T2
,并且T2
的等级大于T3
,则T1
的等级大于T3
。
整数转换等级也用于整型提升的定义中。
[编辑] 浮点转换等级和子等级
[编辑] 浮点转换等级
每个浮点类型都有一个浮点转换等级,定义如下
- 标准浮点类型的等级按顺序递减
- long double
- double
- float
|
(自 C++23 起) |
浮点转换子等级具有相等浮点转换等级的浮点类型按浮点转换子等级排序。子等级在具有相等等级的类型之间形成全序关系。 类型 |
(自 C++23 起) |
[编辑] 用法
浮点转换等级和子等级也用于
- 确定不同浮点类型之间的转换可以是隐式的还是窄化转换,
- 区分重载解析中的转换序列,
|
(自 C++23 起) |
- 确定 std::complex 的 转换构造函数是否是显式的,或
- 确定如果将不同浮点类型的参数传递给 common 或 special 数学函数,则确定通用浮点类型。
[编辑] 缺陷报告
以下行为变更缺陷报告被追溯应用于先前发布的 C++ 标准。
DR | 应用于 | 已发布行为 | 正确行为 |
---|---|---|---|
CWG 1642 | C++98 | 常用算术转换可能涉及左值 | 首先应用左值到右值转换 |
CWG 2528 | C++20 | unsigned char 之间的三路比较 和 unsigned int 是非良构的,因为 中间的整型提升[1] |
基于提升后的类型确定通用类型 无需实际提升操作数[2] 实际提升操作数[2] |
CWG 2892 | C++98 | 当两个操作数都是相同的 浮点类型时,“不需要进一步转换”的含义不明确 浮点类型时,“不需要进一步转换”的含义不明确 |
更改为“不执行进一步的 转换” |