Namespaces
Variants

std:: bit_cast

From cppreference.net
Utilities library
Défini dans l'en-tête <bit>
template < class To, class From >
constexpr To bit_cast ( const From & from ) noexcept ;
(depuis C++20)

Obtenez une valeur de type To en réinterprétant la représentation objet de From . Chaque bit dans la représentation valeur de l'objet To retourné est égal au bit correspondant dans la représentation objet de from . Les valeurs des bits de remplissage dans l'objet To retourné sont non spécifiées.

S'il n'existe aucune valeur de type To correspondant à la représentation de valeur produite, le comportement est indéfini. S'il existe plusieurs valeurs de ce type, la valeur produite n'est pas spécifiée.

Un bit dans la représentation de la valeur du résultat est indéterminé s'il

  • ne correspond pas à un bit dans la représentation de la valeur de From (c'est-à-dire qu'il correspond à un bit de remplissage), ou
  • correspond à un bit d'un objet qui (jusqu'à C++26) pour lequel le plus petit objet englobant (depuis C++26) n'est pas dans sa durée de vie , ou
  • a une valeur indéterminée .

Un bit dans la représentation de la valeur du résultat est erroné s'il correspond à un bit pour lequel le plus petit objet englobant a une valeur erronée .

(since C++26)


Le résultat ne contient par ailleurs aucune valeur indéterminée ou erronée.

Pour chaque bit dans la représentation de la valeur du résultat qui est indéterminé, le plus petit objet contenant ce bit a une valeur indéterminée ; le comportement est indéfini sauf si cet objet est d'un type adapté à l'initialisation .

Le résultat ne contient par ailleurs aucune valeur indéterminée.

(jusqu'en C++26)

Pour chaque bit b dans la représentation de la valeur du résultat qui est indéterminé ou erroné, soit u le plus petit objet contenant b :

  • Si u est d'un type adapté à l'initialisation , u a une valeur indéterminée si l'un des bits de sa représentation de valeur est indéterminé, ou sinon a une valeur erronée.
  • Sinon, si b est indéterminé, le comportement est indéfini.
  • Sinon, le comportement est erroné , et le résultat est comme spécifié ci-dessus.
(depuis C++26)

Cette surcharge participe à la résolution de surcharge seulement si sizeof ( To ) == sizeof ( From ) et que les deux types To et From sont des types TriviallyCopyable .

Ce modèle de fonction est constexpr si et seulement si chacun des types To , From et les types de tous les sous-objets de To et From :

  • n'est pas un type union ;
  • n'est pas un type pointeur ;
  • n'est pas un type pointeur vers membre ;
  • n'est pas un type qualifié volatile ; et
  • n'a pas de membre de données non statique de type référence.

Table des matières

Paramètres

de - la source de bits pour la valeur de retour

Valeur de retour

Un objet de type To dont la représentation de la valeur est telle que décrite ci-dessus.

Implémentation possible

Pour implémenter std::bit_cast , en ignorant le fait que c'est constexpr , std::memcpy peut être utilisé, quand c'est nécessaire, pour interpréter la représentation objet comme celle d'un autre type :

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>
// Le support constexpr nécessite de la magie du compilateur
bit_cast(const From& src) noexcept
{
    static_assert(std::is_trivially_constructible_v<To>,
        "Cette implémentation nécessite en plus "
        "que le type de destination soit trivialement constructible");
    To dst;
    std::memcpy(&dst, &src, sizeof(To));
    return dst;
}

Notes

reinterpret_cast (ou un cast explicite équivalent) entre des types pointeur ou référence ne doit pas être utilisé pour réinterpréter la représentation d'objet dans la plupart des cas en raison de la règle d'aliasing de type .

Macro de test de fonctionnalité Valeur Norme Fonctionnalité
__cpp_lib_bit_cast 201806L (C++20) std::bit_cast

Exemple

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

Sortie possible :

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

Rapports de défauts

Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.

DR Appliqué à Comportement tel que publié Comportement correct
CWG 2482
( P1272R4 )
C++20 il n'était pas spécifié si un UB se produirait lors de l'utilisation de bits indéterminés spécifié

Voir aussi

crée implicitement des objets dans un stockage donné avec la représentation d'objet réutilisée
(modèle de fonction)