通常の算術変換
From cppreference.com
算術型または列挙型のオペランドを期待する多くの二項演算子は、変換を行い、同様の方法で結果型を生成します。その目的は、結果の型でもある共通の型を生成することです。このパターンは「通常の算術変換」と呼ばれます。
目次 |
[編集] 定義
通常の算術変換は次のように定義されます。
[編集] ステージ1
両方のオペランドにlvalue-to-rvalue変換を適用し、結果のprvalueを元のオペランドの代わりに残りのプロセスで使用します。
[編集] ステージ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が符号付きの場合)を除く、2つの符号付き整数型は、それらが同じ表現を持っていても、同じランクを持ちません。
- 符号付き整数型のランクは、幅が小さい任意の符号付き整数型よりも大きいです。
- 次の整数型のランクは、順に減少します。
|
(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の変換コンストラクタが明示的であるかどうかを判断する。
- 異なる浮動小数点型の引数が共通または特殊な数学関数に渡された場合に、共通の浮動小数点型を決定する。
[編集] 不具合報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| CWG 1642 | C++98 | 通常の算術変換はlvalueを伴う可能性がある | lvalue-to-rvalue変換を最初に適用する |
| CWG 2528 | C++20 | unsigned charとunsigned intの3方向比較は、 中間整数昇格のため、不正形式となる [1] |
オペランドを実際に昇格させることなく、 昇格された型に基づいて共通の型を決定する [2] |
| CWG 2892 | C++98 | 両方のオペランドが同じ 浮動小数点型である場合、「それ以上の 変換は必要ない」という意味が不明確 |
「それ以上の 変換は実行されない」に変更された |