std::bit_cast
| ヘッダ <bit> で定義 |
||
| template< class To, class From > constexpr To bit_cast( const From& from ) noexcept; |
(C++20以降) | |
From のオブジェクト表現を再解釈することによって、型 To の値を取得します。返された To オブジェクトの 値表現 内のすべてのビットは、from の オブジェクト表現 内の対応するビットと等しくなります。返された To オブジェクトのパディングビットの値は未規定です。
生成された値表現に対応する型 To の値がない場合、動作は未定義です。そのような値が複数ある場合、どの値が生成されるかは未規定です。
結果の値表現内のビットは、以下の場合に *不定* (indeterminate) となります。
Fromの値表現内のビットに対応しない場合(すなわち、パディングビットに対応する場合)、または- オブジェクトのビットに対応する場合で、そのオブジェクトが(C++26まで)最も小さい囲みオブジェクトのビットに対応する場合で、その最も小さい囲みオブジェクトが(C++26以降)その 生存期間 内にない場合、または
- 不定値 を持つ場合。
|
結果の値表現内のビットは、最も小さい囲みオブジェクトが 誤り値 を持つビットに対応する場合に *誤り* (erroneous) となります。 |
(C++26以降) |
結果には、上記以外に不定値または誤り値は含まれません。
|
結果の値表現内で不定である各ビットについて、そのビットを含む最も小さいオブジェクトは不定値を持ちます。そのオブジェクトが 未初期化フレンドリーな型 でない限り、動作は未定義です。 結果には、上記以外に不定値は含まれません。 |
(C++26まで) |
|
結果の値表現内で不定または誤りである各ビット b について、b を囲む最も小さいオブジェクトを u とします。
|
(C++26以降) |
このオーバーロードは、sizeof(To) == sizeof(From) であり、かつ To と From の両方が TriviallyCopyable 型である場合にのみオーバーロード解決に参加します。
この関数テンプレートは、To、From、および To と From のすべてのサブオブジェクトの型がそれぞれ以下の場合にのみ constexpr となります。
- 共用体型ではないこと。
- ポインタ型ではないこと。
- メンバポインタ型ではないこと。
- volatile修飾型ではないこと。そして
- 参照型の非静的データメンバを持たないこと。
目次 |
[編集] パラメータ
| from | - | 戻り値のビットのソース |
[編集] 戻り値
上記で説明された値表現を持つ型 To のオブジェクト。
[編集] 可能な実装
std::bit_cast を実装するには、それが constexpr であるという事実を無視して、オブジェクト表現を別の型のものとして解釈する必要がある場合に std::memcpy を使用できます。
template<class To, class From> std::enable_if_t< sizeof(To) == sizeof(From) && std::is_trivially_copyable_v<From> && std::is_trivially_copyable_v<To>, To> // constexpr support needs compiler magic bit_cast(const From& src) noexcept { static_assert(std::is_trivially_constructible_v<To>, "This implementation additionally requires " "destination type to be trivially constructible"); To dst; std::memcpy(&dst, &src, sizeof(To)); return dst; }
[編集] 注釈
reinterpret_cast(または同等の 明示的なキャスト)をポインタ型または参照型の間で使用してオブジェクト表現を再解釈することは、型エイリアシング規則 のため、ほとんどの場合避けるべきです。
| 機能テストマクロ | 値 | 規格 | 機能 |
|---|---|---|---|
__cpp_lib_bit_cast |
201806L |
(C++20) | std::bit_cast
|
[編集] 例
#include <bit> #include <cstdint> #include <iostream> constexpr double f64v = 19880124.0; constexpr auto u64v = std::bit_cast<std::uint64_t>(f64v); static_assert(std::bit_cast<double>(u64v) == f64v); // round-trip constexpr std::uint64_t u64v2 = 0x3fe9000000000000ull; constexpr auto f64v2 = std::bit_cast<double>(u64v2); static_assert(std::bit_cast<std::uint64_t>(f64v2) == u64v2); // round-trip int main() { std::cout << "std::bit_cast<std::uint64_t>(" << std::fixed << f64v << ") == 0x" << std::hex << u64v << '\n' << "std::bit_cast<double>(0x" << std::hex << u64v2 << ") == " << std::fixed << f64v2 << '\n'; }
実行結果の例
std::bit_cast<std::uint64_t>(19880124.000000) == 0x4172f58bc0000000 std::bit_cast<double>(0x3fe9000000000000) == 0.781250
[編集] 欠陥報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| CWG 2482 (P1272R4) |
C++20 | 不定ビットが関与した場合に未定義動作が発生するかどうかは未規定でした。 | 指定された |
[編集] 関連項目
| オブジェクト表現を再利用して、与えられたストレージ内にオブジェクトを暗黙的に作成します (関数テンプレート) |