名前空間
変種
操作

std::bit_cast

提供: cppreference.com
< cpp‎ | numeric
ヘッダ <bit> で定義
template< class To, class From >
constexpr To bit_cast(const From& from) noexcept;
(C++20以上)

from のオブジェクト表現を再解釈することによって To 型の値を取得します。 返された To オブジェクトの値表現内のすべてのビットは from のオブジェクト表現内の対応するビットと等しくなります。 返された To オブジェクト内のパディングビットの値は未規定です。

生成された値表現に対応する To 型の値が存在しない場合、動作は未定義です。 対応する値が複数ある場合、どの値が生成されるかは未規定です。

このオーバーロードは、sizeof(To) == sizeof(From) であり、 ToFrom がどちらも TriviallyCopyable な型である場合にのみ、オーバーロード解決に参加します。

この関数テンプレートは、 ToFrom のそれぞれが、および ToFrom のすべての部分オブジェクトが以下の内容をすべて満たす場合に限り、 constexpr です。

  • 共用体型でない。
  • ポインタ型でない。
  • メンバポインタ型でない。
  • volatile 修飾された型でない。
  • 参照型の非静的データメンバを持たない。

[編集] 戻り値

上で説明した通りの値表現を持つ To 型のオブジェクト。

[編集] ノート

ポインタまたは参照型の間の reinterpret_cast (または同等の明示的なキャスト) は、型のエイリアシングルールのため、ほとんどの場合においてオブジェクト表現の再解釈に使用することはできません。

std::bit_cast 以前でオブジェクト表現を別の型のオブジェクト表現として解釈する必要があるときは std::memcpy を使用することができます。

template <class To, class From>
typename std::enable_if<
    (sizeof(To) == sizeof(From)) &&
    std::is_trivially_copyable<From>::value &&
    std::is_trivial<To>::value,
    // この実装は To がトリビアルにデフォルト構築可能であることを要求します。
    To>::type
// constexpr のサポートはコンパイラマジックが必要です。
bit_cast(const From &src) noexcept
{
    To dst;
    std::memcpy(&dst, &src, sizeof(To));
    return dst;
}

[編集]

#include <cstdint>
#include <bit>
#include <iostream>
 
constexpr double f64v = 19880124.0;
constexpr auto u64v = std::bit_cast<std::uint64_t>(f64v);
 
constexpr std::uint64_t u64v2 = 0x3fe9000000000000ull;
constexpr auto f64v2 = std::bit_cast<double>(u64v2);
 
int main()
{
    std::cout
        << std::fixed <<f64v << "f64.to_bits() == 0x"
        << std::hex << u64v << "u64\n";
 
    std::cout
        << "f64::from_bits(0x" << std::hex << u64v2 << "u64) == "
        << std::fixed << f64v2 << "f64\n";
}

出力例:

19880124.000000f64.to_bits() == 0x4172f58bc0000000u64
f64::from_bits(0x3fe9000000000000u64) == 0.781250f64