std::as_bytes / as_writable_bytes

std::as_bytes / as_writable_bytes (span을 바이트 뷰로)

span의 원소들의 객체 표현(object representation)에 대한 뷰를 얻는 함수예요. std::byte들의 span을 돌려줘요. 바이트 단위 접근이 필요할 때 유용해요. C++20부터 있어요.

출처: cppreference

본문

<span> 헤더에 정의돼 있어요.

template< class T, std::size_t N >
std::span<const std::byte, S/* see below */>
    as_bytes( std::span<T, N> s ) noexcept;            // (1)

template< class T, std::size_t N >
std::span<std::byte, S/* see below */>
    as_writable_bytes( std::span<T, N> s ) noexcept;   // (2)

span s의 원소들의 객체 표현에 대한 뷰를 얻어요. Nstd::dynamic_extent면 반환된 span의 범위 Sstd::dynamic_extent이고, 그렇지 않으면 sizeof(T) * N이에요.

as_writable_bytesstd::is_const_v<T>false일 때만 오버로드 해석에 참여해요.

  • 반환 값:
    • (1) {reinterpret_cast<const std::byte*>(s.data()), s.size_bytes()}로 만든 span.
    • (2) {reinterpret_cast<std::byte*>(s.data()), s.size_bytes()}로 만든 span.

예제를 보면 float의 바이트 표현을 확인할 수 있어요.

#include <cstddef>
#include <iomanip>
#include <iostream>
#include <span>

void print(float const x, std::span<const std::byte> const bytes)
{
    std::cout << std::setprecision(6) << std::setw(8) << x << " = { "
              << std::hex << std::uppercase << std::setfill('0');
    for (auto const b : bytes)
        std::cout << std::setw(2) << std::to_integer<int>(b) << ' ';
    std::cout << std::dec << "}\n";
}

int main()
{
    float data[1]{3.141592f};

    auto const const_bytes = std::as_bytes(std::span{data});
    print(data[0], const_bytes);

    auto const writable_bytes = std::as_writable_bytes(std::span{data});

    // IEEE 754에서 MSB가 부호 비트. 부호 비트를 바꿔보기.
    writable_bytes[3] |= std::byte{0B1000'0000};

    print(data[0], const_bytes);
}

가능한 출력:

 3.14159 = { D8 0F 49 40 }
-3.14159 = { D8 0F 49 C0 }

이렇게 as_bytes는 객체의 원시 메모리 바이트를 읽거나, as_writable_bytes로 수정할 수 있는 뷰를 제공해요. 직렬화·패킹·포맷 변환 같은 저수준 작업에 유용해요.

더 알아보기 (Learn more)

cppreference