Namespaces
Variants

std:: bit_cast

From cppreference.net
Utilities library
Definido en el encabezado <bit>
template < class To, class From >
constexpr To bit_cast ( const From & from ) noexcept ;
(desde C++20)

Obtenga un valor de tipo To reinterpretando la representación del objeto de From . Cada bit en la representación de valor del objeto To devuelto es igual al bit correspondiente en la representación de objeto de from . Los valores de los bits de relleno en el objeto To devuelto no están especificados.

Si no hay ningún valor de tipo To que corresponda a la representación de valor producida, el comportamiento es indefinido. Si hay múltiples valores de este tipo, qué valor se produce no está especificado.

Un bit en la representación de valor del resultado es indeterminado si

  • no corresponde a un bit en la representación de valor de From (es decir, corresponde a un bit de relleno), o
  • corresponde a un bit de un objeto que (until C++26) para el cual el objeto contenedor más pequeño (since C++26) no está dentro de su lifetime , o
  • tiene un indeterminate value .

Un bit en la representación de valor del resultado es erróneo si corresponde a un bit para el cual el objeto contenedor más pequeño tiene un valor erróneo .

(since C++26)


El resultado no contiene ningún otro valor indeterminado o erróneo.

Para cada bit en la representación de valor del resultado que sea indeterminado, el objeto más pequeño que contiene ese bit tiene un valor indeterminado; el comportamiento es indefinido a menos que ese objeto sea de un tipo amigable a la no inicialización .

El resultado no contiene ningún otro valor indeterminado.

(hasta C++26)

Para cada bit b en la representación de valor del resultado que sea indeterminado o erróneo, sea u el objeto más pequeño que contiene b :

  • Si u es de tipo amigable a la no inicialización , u tiene un valor indeterminado si cualquier bit en su representación de valor es indeterminado, o de lo contrario tiene un valor erróneo.
  • De lo contrario, si b es indeterminado, el comportamiento es indefinido.
  • De lo contrario, el comportamiento es erróneo , y el resultado es como se especificó anteriormente.
(desde C++26)

Esta sobrecarga participa en la resolución de sobrecarga solo si sizeof ( To ) == sizeof ( From ) y ambos To y From son tipos TriviallyCopyable .

Esta plantilla de función es constexpr si y solo si cada uno de To , From y los tipos de todos los subobjetos de To y From :

  • no es un tipo unión;
  • no es un tipo puntero;
  • no es un tipo puntero a miembro;
  • no es un tipo calificado como volátil; y
  • no tiene ningún miembro de datos no estáticos de tipo referencia.

Contenidos

Parámetros

desde - la fuente de bits para el valor de retorno

Valor de retorno

Un objeto de tipo To cuya representación de valor es como se describe anteriormente.

Implementación posible

Para implementar std::bit_cast , ignorando el hecho de que es constexpr , std::memcpy puede utilizarse, cuando sea necesario, para interpretar la representación del objeto como la de otro tipo:

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>
// el soporte constexpr requiere magia del compilador
bit_cast(const From& src) noexcept
{
    static_assert(std::is_trivially_constructible_v<To>,
        "Esta implementación requiere adicionalmente "
        "que el tipo destino sea trivialmente construible");
    To dst;
    std::memcpy(&dst, &src, sizeof(To));
    return dst;
}

Notas

reinterpret_cast (o el equivalente cast explícito ) entre tipos de puntero o referencia no debe utilizarse para reinterpretar la representación de objetos en la mayoría de los casos debido a la regla de aliasing de tipos .

Macro de prueba de características Valor Estándar Característica
__cpp_lib_bit_cast 201806L (C++20) std::bit_cast

Ejemplo

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

Salida posible:

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

Informes de defectos

Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.

DR Aplicado a Comportamiento publicado Comportamiento correcto
CWG 2482
( P1272R4 )
C++20 no estaba especificado si ocurriría UB al involucrar bits indeterminados especificado

Véase también

crea implícitamente objetos en el almacenamiento dado reutilizando la representación del objeto
(plantilla de función)