簡単な答え:
何reinterpret_cast
の略かわからない場合は、使用しないでください。将来必要になる場合は、わかります。
完全な答え:
基本的な数の型を考えてみましょう。
たとえば、プロセッサに変換する場合int(12)
、unsigned float (12.0f)
両方の数値のビット表現が異なるため、いくつかの計算を呼び出す必要があります。これがそのstatic_cast
略です。
一方、reinterpret_cast
CPU を呼び出すと、計算は呼び出されません。メモリ内のビットのセットを、別のタイプがあるかのように扱うだけです。したがって、このキーワードを使用して変換int*
するfloat*
と、新しい値 (ポインターの参照解除後) は、数学的な意味で古い値とは何の関係もありません。
例:reinterpret_cast
1 つの理由 - バイト順 (エンディアン) のために移植性がないのは事実ですしかし、これは驚くべきことに、それを使用する最良の理由であることがよくあります。例を想像してみましょう: ファイルからバイナリ 32 ビット数を読み取る必要があり、それがビッグ エンディアンであることがわかっています。コードは汎用的である必要があり、ビッグ エンディアン (ARM など) およびリトル エンディアン (x86 など) システムで正しく動作する必要があります。したがって、バイトオーダーを確認する必要があります。コンパイル時によく知られているので、関数を書くことができconstexpr
ます:これを達成する関数を書くことができます:
/*constexpr*/ bool is_little_endian() {
std::uint16_t x=0x0001;
auto p = reinterpret_cast<std::uint8_t*>(&x);
return *p != 0;
}
説明:x
メモリ内のバイナリ表現は0000'0000'0000'0001
(ビッグ) または0000'0001'0000'0000
(リトルエンディアン) の可能性があります。再解釈キャストした後、p
ポインターの下のバイトはそれぞれ0000'0000
または0000'0001
ます。静的キャストを使用すると0000'0001
、使用されているエンディアンに関係なく、常に になります。
編集:
最初のバージョンでは、サンプル関数is_little_endian
を にしconstexpr
ました。最新の gcc (8.3.0) では正常にコンパイルされますが、標準では違法とされています。clang コンパイラはそれをコンパイルすることを拒否します (これは正しいです)。