std::bit_cast
| Definiert in Header <bit> |
||
| template< class To, class From > constexpr To bit_cast( const From& from ) noexcept; |
(seit C++20) | |
Ermöglicht das Erhalten eines Werts vom Typ To durch Neuinterpretation der Objekt-Repräsentation von From. Jedes Bit in der Wert-Repräsentation des zurückgegebenen To-Objekts ist gleich dem entsprechenden Bit in der Objekt-Repräsentation von from. Die Werte von Füllbits im zurückgegebenen To-Objekt sind nicht spezifiziert.
Wenn es keinen Wert vom Typ To gibt, der der erzeugten Wert-Repräsentation entspricht, ist das Verhalten undefiniert. Wenn es mehrere solche Werte gibt, ist nicht spezifiziert, welcher Wert erzeugt wird.
Ein Bit in der Wert-Repräsentation des Ergebnisses ist unbestimmt, wenn es
- nicht einem Bit in der Wert-Repräsentation von
Fromentspricht (d. h. es entspricht einem Füllbit), oder - einem Bit entspricht eines Objekts, das(bis C++26)dessen kleinstes umschließendes Objekt(seit C++26) nicht innerhalb seiner Lebensdauer liegt, oder
- einen unbestimmten Wert hat.
|
Ein Bit in der Wert-Repräsentation des Ergebnisses ist fehlerhaft, wenn es einem Bit entspricht, für das das kleinste umschließende Objekt einen fehlerhaften Wert hat. |
(seit C++26) |
Das Ergebnis enthält ansonsten keine unbestimmten oder fehlerhaften Werte.
|
Für jedes Bit in der Wert-Repräsentation 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 hat einen uninitialisiert-freundlichen Typ. Das Ergebnis enthält ansonsten keine unbestimmten Werte. |
(bis C++26) |
|
Für jedes Bit b in der Wert-Repräsentation des Ergebnisses, das unbestimmt oder fehlerhaft ist, sei u das kleinste Objekt, das b umschließt.
|
(seit C++26) |
Diese Überladung nimmt nur an der Auflösung von Überladungen teil, wenn sizeof(To) == sizeof(From) und sowohl To als auch From TriviallyCopyable-Typen sind.
Diese Funktionsschablone ist genau dann constexpr, wenn jeder der Typen To, From und die Typen aller Unterobjekte von To und From
- kein Union-Typ ist;
- kein Zeigertyp ist;
- kein Zeiger auf ein Member-Typ ist;
- kein flüchtig qualifizierter Typ ist; und
- kein nicht-statisches Datenmitglied vom Referenztyp hat.
Inhalt |
[bearbeiten] Parameter
| from | - | die Quelle der Bits für den Rückgabewert |
[bearbeiten] Rückgabewert
Ein Objekt vom Typ To, dessen Wert-Repräsentation wie oben beschrieben ist.
[bearbeiten] Mögliche Implementierung
Um std::bit_cast zu implementieren, wobei die Tatsache ignoriert wird, dass es constexpr ist, kann std::memcpy verwendet werden, um die Objekt-Repräsentation als einen anderen Typ zu interpretieren, wenn dies erforderlich ist.
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; }
[bearbeiten] Hinweise
reinterpret_cast (oder ein äquivalenter expliziter Cast) zwischen Zeiger- oder Referenztypen darf aufgrund der Typ-Aliasing-Regel in den meisten Fällen nicht zur Neuinterpretation der Objekt-Repräsentation verwendet werden.
| Feature-Test-Makro | Wert | Std | Feature |
|---|---|---|---|
__cpp_lib_bit_cast |
201806L |
(C++20) | std::bit_cast
|
[bearbeiten] 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); // 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'; }
Mögliche Ausgabe
std::bit_cast<std::uint64_t>(19880124.000000) == 0x4172f58bc0000000 std::bit_cast<double>(0x3fe9000000000000) == 0.781250
[bearbeiten] Fehlerberichte
Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | angewendet auf | Verhalten wie veröffentlicht | Korrigiertes Verhalten |
|---|---|---|---|
| CWG 2482 (P1272R4) |
C++20 | es war nicht spezifiziert, ob bei Beteiligung von unbestimmten Bits ein UB auftreten würde | spezifiziert |
[bearbeiten] Siehe auch
| erstellt implizit Objekte in gegebenem Speicher, wobei die Objekt-Repräsentation wiederverwendet wird (Funktions-Template) |