Namespaces
Variants

std:: bit_cast

From cppreference.net
Utilities library
헤더 파일에 정의됨 <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부터) 자신의 수명 범위 내에 있지 않은 경우, 또는
  • indeterminate value 를 가지는 경우.

결과의 값 표현에서 한 비트는, 해당 비트에 대해 가장 작은 enclosing object가 erroneous value 를 가지는 경우 erroneous 입니다.

(since C++26)


결과는 그 외의 경우 어떤 불확정(indeterminate) 값이나 오류(erroneous) 값도 포함하지 않습니다.

결과의 값 표현에서 불확정(Indeterminate)인 각 비트에 대해, 해당 비트를 포함하는 가장 작은 객체는 불확정 값을 가집니다; 해당 객체가 초기화 친화적 형식(uninitialized-friendly type) 이 아닌 경우 동작은 정의되지 않습니다.

결과는 그 외의 경우 어떤 불확정 값도 포함하지 않습니다.

(C++26 이전)

결과의 값 표현에서 불확정(indeterminate)이거나 오류(erroneous)인 각 비트 b 에 대해, b 를 포함하는 가장 작은 객체를 u 라고 하면:

  • 만약 u 초기화 친화적 형식(uninitialized-friendly type) 인 경우, u 는 그 값 표현의 어떤 비트가 불확정(indeterminate)인 경우 불확정 값을 가지며, 그렇지 않으면 오류 값(erroneous value)을 가집니다.
  • 그렇지 않고 b 가 불확정(indeterminate)인 경우, 동작은 정의되지 않습니다.
  • 그렇지 않으면 동작은 오류(erroneous) 이며, 결과는 위에서 명시된 것과 같습니다.
(C++26 이후)

이 오버로드는 다음 조건에서만 오버로드 해결에 참여합니다: sizeof ( To ) == sizeof ( From ) 그리고 To From 모두 TriviallyCopyable 타입인 경우입니다.

이 함수 템플릿은 다음 각 항목이 constexpr 일 경우에만 To , From 그리고 To From 의 모든 하위 객체들의 타입들:

  • 유니온 타입이 아닙니다;
  • 포인터 타입이 아닙니다;
  • 멤버 포인터 타입이 아닙니다;
  • 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 지원은 컴파일러 매직이 필요함
bit_cast(const From& src) noexcept
{
    static_assert(std::is_trivially_constructible_v<To>,
        "이 구현은 추가적으로 대상 타입이 "
        "trivially constructible해야 함을 요구합니다");
    To dst;
    std::memcpy(&dst, &src, sizeof(To));
    return dst;
}

참고 사항

reinterpret_cast (또는 이에 상응하는 explicit cast )는 포인터나 참조 타입 간에 사용될 경우 대부분의 경우 type aliasing rule 으로 인해 객체 표현을 재해석하는 데 사용되어서는 안 됩니다.

기능 테스트 매크로 표준 기능
__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); // 왕복 변환
constexpr std::uint64_t u64v2 = 0x3fe9000000000000ull;
constexpr auto f64v2 = std::bit_cast<double>(u64v2);
static_assert(std::bit_cast<std::uint64_t>(f64v2) == u64v2); // 왕복 변환
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 불확정 비트를 포함할 때 UB 발생 여부가 명시되지 않았음 명시됨

참고 항목

주어진 저장 공간에서 객체 표현을 재사용하여 객체를 암시적으로 생성함
(function template)