std::start_lifetime_as, std::start_lifetime_as_array
来自cppreference.com
                    
                                        
                    
                    
                                                            
                    | 在标头  <memory>定义 | ||
| start_lifetime_as | ||
| template< class T > T* start_lifetime_as( void* p ) noexcept; | (1) | (C++23 起) | 
| template< class T > const T* start_lifetime_as( const void* p ) noexcept; | (2) | (C++23 起) | 
| template< class T > volatile T* start_lifetime_as( volatile void* p ) noexcept; | (3) | (C++23 起) | 
| template< class T > const volatile T* start_lifetime_as( const volatile void* p ) noexcept; | (4) | (C++23 起) | 
| start_lifetime_as_array | ||
| template< class T > T* start_lifetime_as_array( void* p, std::size_t n ) noexcept; | (5) | (C++23 起) | 
| template< class T > const T* start_lifetime_as_array( const void* p, | (6) | (C++23 起) | 
| template< class T > volatile T* start_lifetime_as_array( volatile void* p, | (7) | (C++23 起) | 
| template< class T > const volatile T* start_lifetime_as_array( const volatile void* p, | (8) | (C++23 起) | 
1-4) 隐式创建类型为 
T、地址为 p 的完整对象以及内嵌于它的对象。每个被创建的可平凡复制 (TriviallyCopyable) 类型 U 对象 obj 的的值以和调用 std::bit_cast<U>(E) 相同的方式确定,除了不实际访问该存储,其中 E 是指代 obj 的 U 类型左值。否则,这种被创建的对象的值未指定。
-  T必须为隐式生存期类型 (ImplicitLifetimeType) 且必须为完整类型,否则程序非良构。
- 若符合以下条件则行为未定义:
-  [p,(char*)p + sizeof(T))不指代作为可由 p 抵达的存储区域的子集的已分配的存储区域,或
-  该区域未对 T适合地对齐。
 
-  
- 注意未指定值能为不确定。
5-8) 隐式创建元素类型为 
T、长度为 n 的数组。精确地说,若 n > 0 为 true 则等价于 std::start_lifetime_as<U>(p),其中 U 为“n 个 T 的数组”。否则函数无效果。
-  T必须为完整类型,否则程序非良构。
- 若符合以下条件则行为未定义:
-  非空的 p 未对 T的数组适合地对齐,或
- n <= std::size_t(-1) / sizeof(T) 为 false,或
-  n > 0 且 [(char*)p,(char*)p + (n * sizeof(T)))不指代作为可由 p 抵达的存储区域的子集的已分配的存储区域。
 
-  非空的 p 未对 
参数
| p | - | 组成对象的区域的地址 | 
| n | - | 要创建的数组的元素数 | 
返回值
1-4) 指向如上所述的完整对象的指针。
5-8) 指向被创建的数组的首元素的指针,若存在该数组;否则返回比较等于 p 的指针。
注解
new (void_ptr) unsigned char[size] 或 new (void_ptr) std::byte[size] 如 std::start_lifetime_as 的无类型版本一样起作用,但它不保持对象表示。
std::start_lifetime_as 处理非数组类型以及已知边界数组,而 std::start_lifetime_as_array 处理未知边界数组。
| 功能特性测试宏 | 值 | 标准 | 备注 | 
|---|---|---|---|
| __cpp_lib_start_lifetime_as | 202207L | (C++23) | Explicit lifetime management | 
示例
运行此代码
#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); // std::cout << d << '\n'; // UB: network_data 不指向一个 complex<float> // auto d = std::launder(*reinterpret_cast<std::complex<float>*>(network_data)); // std::cout << d << '\n'; // 可能的 UB,与 CWG1997 相关: // 隐式创建的 complex<float> 可能保有不确定值 auto d = *std::start_lifetime_as<std::complex<float>>(network_data); std::cout << d << '\n'; // OK }
可能的输出:
(0.1,0.2)
引用
- C++23 标准(ISO/IEC 14882:2023):
- 20.2.6 Explicit lifetime management [obj.lifetime]
 
参阅
| (C++20) | 将一个类型的对象表示重解释为另一类型的对象表示 (函数模板) | 
| 转换 span为对其底层字节的视图(函数模板) |