memory_start_lifetime_as

memory_start_lifetime_as (std::start_lifetime_as)

<memory> 헤더에 정의되어 있어요. 주소 p에 타입 T의 완전 객체와 그 안에 중첩된 객체들을 암시적으로 생성해요. 명시적 수명 관리(explicit lifetime management)를 위한 함수예요. C++23부터 도입됐어요.

출처: cppreference

본문

template< class T >
T* start_lifetime_as( void* p ) noexcept;                       // (1) since C++23
template< class T >
const T* start_lifetime_as( const void* p ) noexcept;           // (2)
template< class T >
volatile T* start_lifetime_as( volatile void* p ) noexcept;     // (3)
template< class T >
const volatile T* start_lifetime_as( const volatile void* p ) noexcept;  // (4)

template< class T >
T* start_lifetime_as_array( void* p, std::size_t n ) noexcept;  // (5) since C++23
template< class T >
const T* start_lifetime_as_array( const void* p, std::size_t n ) noexcept;  // (6)
template< class T >
volatile T* start_lifetime_as_array( volatile void* p, std::size_t n ) noexcept;  // (7)
template< class T >
const volatile T* start_lifetime_as_array( const volatile void* p, std::size_t n ) noexcept;  // (8)
  • (1-4) 주소가 p인 타입 T의 완전 객체와 그 안에 중첩된 객체들을 암시적으로 생성해요. TriviallyCopyable 타입 U의 각 생성된 객체 obj의 값은 저장 공간에 실제로 접근하지 않는 다는 점을 빼고 std::bit_cast<U>(E) 호출과 같은 방식으로 결정돼요. 그 외 생성된 객체의 값은 미지정이에요.
    • T는 ImplicitLifetimeType이어야 하고 완전 타입이어야 해요. [p, (char*)p + sizeof(T))p를 통해 도달 가능한 할당 저장 공간의 부분집합을 나타내지 않거나, 그 영역이 T에 적합하게 정렬되지 않으면 동작은 미정의예요.
  • (5-8) 요소 타입 T·길이 n의 배열을 암시적으로 생성해요. n > 0이면 U가 "n개의 T 배열" 타입인 std::start_lifetime_as<U>(p)와 동등해요. 그 외에는 효과가 없어요.

반환값

  • (1-4) 위에서 설명한 완전 객체에 대한 포인터.
  • (5-8) 생성된 배열의 첫 요소에 대한 포인터. 없으면 p와 동등하게 비교되는 포인터.

주의 (Notes)

new (ptr) unsigned char[size] 또는 new (ptr) std::byte[size]start_lifetime_as의 타입 없는 버전으로 동작하지만 객체 표현을 유지하지 않아요. start_lifetime_as는 비-배열 타입과 경계를 아는 배열을, start_lifetime_as_array는 경계를 모르는 배열을 다뤄요.

기능 테스트 매크로는 __cpp_lib_start_lifetime_as(202207L, C++23)예요.

예제

#include <complex>
#include <iostream>
#include <memory>

int main()
{
    alignas(std::complex<float>) unsigned char network_data[sizeof(std::complex<float>)]
    {
        0xcd, 0xcc, 0xcc, 0x3d, 0xcd, 0xcc, 0x4c, 0x3e
    };

    // auto d = *reinterpret_cast<std::complex<float>*>(network_data);  // UB
    auto d2 = *std::start_lifetime_as<std::complex<float>>(network_data);
    std::cout << d2 << '\n'; // OK
}

가능한 출력:

(0.1,0.2)

더 알아보기 (Learn more)

cppreference