Namespaces
Variants

std:: bit_cast

From cppreference.net
Utilities library
Definiert im Header <bit>
template < class To, class From >
constexpr To bit_cast ( const From & from ) noexcept ;
(seit C++20)

Erhalten Sie einen Wert vom Typ To durch Neuinterpretation der Objektdarstellung von From . Jedes Bit in der Wertedarstellung des zurückgegebenen To -Objekts entspricht dem entsprechenden Bit in der Objektdarstellung von from . Die Werte der Füllbits im zurückgegebenen To -Objekt sind nicht spezifiziert.

Wenn es keinen Wert des Typs To gibt, der der erzeugten Wertdarstellung entspricht, ist das Verhalten undefiniert. Wenn es mehrere solche Werte gibt, ist nicht spezifiziert, welcher Wert erzeugt wird.

Ein Bit in der Wertdarstellung des Ergebnisses ist unbestimmt , wenn es

  • entspricht keinem Bit in der Wertdarstellung von From (d.h. es entspricht einem Padding-Bit), oder
  • entspricht einem Bit eines Objekts, das (bis C++26) für das das kleinste umschließende Objekt (seit C++26) sich nicht innerhalb seiner Lebensdauer befindet, oder
  • einen unbestimmten Wert hat.

Ein Bit in der Wertdarstellung des Ergebnisses ist fehlerhaft , wenn es einem Bit entspricht, für das das kleinste umschließende Objekt einen fehlerhaften Wert hat.

(since C++26)


Das Ergebnis enthält ansonsten keine unbestimmten oder fehlerhaften Werte.

Für jedes Bit in der Wertdarstellung des Ergebnisses, das unbestimmt ist, hat das kleinste Objekt, das dieses Bit enthält, einen unbestimmten Wert; das Verhalten ist undefiniert, es sei denn, das Objekt ist von einem uninitialized-friendly type .

Das Ergebnis enthält ansonsten keine unbestimmten Werte.

(bis C++26)

Für jedes Bit b in der Wertdarstellung des Ergebnisses, das unbestimmt oder fehlerhaft ist, sei u das kleinste Objekt, das b umschließt:

  • Wenn u vom uninitialized-friendly type ist, hat u einen unbestimmten Wert, falls irgendeines der Bits in seiner Wertdarstellung unbestimmt ist, oder andernfalls einen fehlerhaften Wert.
  • Andernfalls, wenn b unbestimmt ist, ist das Verhalten undefiniert.
  • Andernfalls ist das Verhalten erroneous , und das Ergebnis ist wie oben angegeben.
(seit C++26)

Diese Überladung nimmt nur dann an der Überladungsauflösung teil, wenn sizeof ( To ) == sizeof ( From ) und sowohl To als auch From TriviallyCopyable -Typen sind.

Diese Funktionsvorlage ist constexpr genau dann, wenn jeder von To , From und die Typen aller Unterobjekte von To und From :

  • ist kein Union-Typ;
  • ist kein Zeigertyp;
  • ist kein Zeiger-auf-Mitglied-Typ;
  • ist kein volatile-qualifizierter Typ; und
  • hat kein nicht-statisches Datenelement vom Referenztyp.

Inhaltsverzeichnis

Parameter

from - die Quelle der Bits für den Rückgabewert

Rückgabewert

Ein Objekt vom Typ To , dessen Wertdarstellung wie oben beschrieben ist.

Mögliche Implementierung

Um std::bit_cast zu implementieren, unter Vernachlässigung der Tatsache, dass es constexpr ist, kann std::memcpy verwendet werden, wenn es erforderlich ist, die Objektdarstellung als die eines anderen Typs zu interpretieren:

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-Unterstützung benötigt Compiler-Magie
bit_cast(const From& src) noexcept
{
    static_assert(std::is_trivially_constructible_v<To>,
        "Diese Implementierung erfordert zusätzlich, "
        "dass der Zieltyp trivial konstruierbar ist");
    To dst;
    std::memcpy(&dst, &src, sizeof(To));
    return dst;
}

Hinweise

reinterpret_cast (oder gleichwertiger expliziter Cast ) zwischen Zeiger- oder Referenztypen sollte in den meisten Fällen nicht zur Neuinterpretation der Objektdarstellung verwendet werden, aufgrund der Type-Aliasing-Regel .

Feature-Test Makro Wert Std Feature
__cpp_lib_bit_cast 201806L (C++20) std::bit_cast

Beispiel

#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); // Rundreise
constexpr std::uint64_t u64v2 = 0x3fe9000000000000ull;
constexpr auto f64v2 = std::bit_cast<double>(u64v2);
static_assert(std::bit_cast<std::uint64_t>(f64v2) == u64v2); // Rundreise
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';
}

Mögliche Ausgabe:

std::bit_cast<std::uint64_t>(19880124.000000) == 0x4172f58bc0000000
std::bit_cast<double>(0x3fe9000000000000) == 0.781250

Fehlerberichte

Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR Angewendet auf Verhalten wie veröffentlicht Korrektes Verhalten
CWG 2482
( P1272R4 )
C++20 es war nicht spezifiziert, ob UB auftreten würde, wenn unbestimmte Bits beteiligt sind spezifiziert

Siehe auch

Erstellt implizit Objekte in gegebenem Speicher unter Wiederverwendung der Objektrepräsentation
(Funktions-Template)