常用算術轉換
來自 cppreference.com
許多期待算術或列舉型別運算元的二元運算子,會以類似的方式引發轉換併產生結果型別。其目的是產生一個公共型別,該型別也是結果的型別。此模式被稱為常規算術轉換(usual arithmetic conversions)。
目錄 |
[編輯] 定義
常規算術轉換定義如下
[編輯] 階段 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) |
[編輯] 整數轉換等級
每個整數型別都有一個整數轉換等級(integer conversion rank),定義如下
- 除了 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
。
整數轉換等級也用於整數提升的定義中。
[編輯] 浮點轉換等級和次等級
[編輯] 浮點轉換等級
每個浮點型別都有一個浮點轉換等級(floating-point conversion rank),定義如下
- 標準浮點型別的等級依次降低
- long double
- double
- float
|
(C++23 起) |
浮點轉換次等級浮點轉換等級相等的浮點型別,透過浮點轉換次等級(floating-point conversion subrank)來排序。次等級在等級相等的型別之間構成一個全序關係。 型別 |
(C++23 起) |
[編輯] 用法
浮點轉換等級和次等級也用於
|
(C++23 起) |
- 確定 std::complex 的轉換建構函式是否為 explicit,或
- 當將不同浮點型別的引數傳遞給通用或特殊數學函式時,確定公共浮點型別。
[編輯] 缺陷報告
下列更改行為的缺陷報告追溯地應用於以前出版的 C++ 標準。
缺陷報告 | 應用於 | 釋出時的行為 | 正確的行為 |
---|---|---|---|
CWG 1642 | C++98 | 常規算術轉換可能涉及左值 | 首先應用左值到右值轉換 |
CWG 2528 | C++20 | unsigned char 和 unsigned int 之間的三路比較非良構,因為 存在中間的整數提升[1] |
基於提升後的型別確定 公共型別,而不需要 實際提升運算元[2] |
CWG 2892 | C++98 | 當兩個運算元都是相同的 浮點型別時,“不需要 進一步轉換”的含義不明確 |
更改為“不會執行 進一步轉換” |