名前空間
変種
操作

std::bit_cast

From cppreference.com
< cpp‎ | numeric
 
 
ユーティリティライブラリ
言語サポート
型のサポート (基本型、RTTI)
ライブラリ機能検査マクロ (C++20)
プログラムユーティリティ
可変引数関数
コルーチンサポート (C++20)
契約サポート (C++26)
三方比較
(C++20)
(C++20)(C++20)(C++20)  
(C++20)(C++20)(C++20)

汎用ユーティリティ
関係演算子 (C++20で非推奨)
 
 
ヘッダ <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 とします。

  • u未初期化フレンドリーな型 の場合、その値表現内のいずれかのビットが不定であれば u は不定値を持ち、そうでなければ誤り値を持ちます。
  • そうでなく、b が不定である場合、動作は未定義です。
  • そうでなく、動作は 誤り であり、結果は上記のように指定されます。
(C++26以降)

このオーバーロードは、sizeof(To) == sizeof(From) であり、かつ ToFrom の両方が TriviallyCopyable 型である場合にのみオーバーロード解決に参加します。

この関数テンプレートは、ToFrom、および ToFrom のすべてのサブオブジェクトの型がそれぞれ以下の場合にのみ 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 不定ビットが関与した場合に未定義動作が発生するかどうかは未規定でした。 指定された

[編集] 関連項目

オブジェクト表現を再利用して、与えられたストレージ内にオブジェクトを暗黙的に作成します
(関数テンプレート) [編集]
English 日本語 中文(简体) 中文(繁體)