Usual arithmetic conversions
多くの二項演算子は、 算術型 または 列挙型 のオペランドを期待し、同様の方法で変換を引き起こし、結果型を生成します。その目的は、結果の型でもある共通の型を生成することです。このパターンは 通常の算術変換 と呼ばれます。
目次 |
定義
通常の算術変換は以下のように定義されます:
ステージ1
両方のオペランドに lvalue-to-rvalue conversion を適用し、結果の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に対応する符号なし整数型となる。
-
|
一方のオペランドが列挙型で、もう一方のオペランドが異なる列挙型または浮動小数点型である場合、この動作は非推奨です。 |
(since C++20)
(until 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 の 変換コンストラクタ が明示的(explicit)かどうかを判定する、または
- 異なる浮動小数点型の引数が 共通 または 特殊 数学関数に渡された場合の共通浮動小数点型を判定する。
不具合報告
以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。
| DR | 適用対象 | 公開時の動作 | 正しい動作 |
|---|---|---|---|
| CWG 1642 | C++98 | 通常の算術変換が左辺値を含む可能性があった | 左辺値から右辺値への変換を先に適用 |
| CWG 2528 | C++20 |
unsigned
char
と
unsigned
int
の三方比較が
中間的な整数昇格により不適格となっていた [1] |
オペランドを実際に昇格させずに、
昇格後の型に基づいて共通の型を決定 [2] |
| CWG 2892 | C++98 |
両オペランドが同じ浮動小数点型の場合、
「これ以上の変換は不要」の意味が不明確だった |
「これ以上の変換は実行されない」
に変更 |