std::start_lifetime_as, std::start_lifetime_as_array
来自 cppreference.cn
定义于头文件 <memory> |
||
std::start_lifetime_as |
||
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) | (since C++23) |
template< class T > volatile T* start_lifetime_as( volatile void* p ) noexcept; |
(3) | (since C++23) |
template< class T > const volatile T* start_lifetime_as( const volatile void* p ) noexcept; |
(4) | (since C++23) |
std::start_lifetime_as_array |
||
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, |
(6) | (since C++23) |
template< class T > volatile T* start_lifetime_as_array( volatile void* p, |
(7) | (since C++23) |
template< class T > const volatile T* start_lifetime_as_array( const volatile void* p, |
(8) | (since 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) | 显式生命周期管理 |
[编辑] 示例
运行此代码
#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 does not point to a complex<float> // auto d1 = *std::launder(reinterpret_cast<std::complex<float>*>(network_data)); // std::cout << d1 << '\n'; // UB: implicitly created objects have dynamic storage // duration and have indeterminate value initially, // even when an array which provides storage for // them has determinate bytes. // See also CWG2721. auto d2 = *std::start_lifetime_as<std::complex<float>>(network_data); std::cout << d2 << '\n'; // OK }
可能的输出
(0.1,0.2)
[编辑] 参考文献
- C++23 标准 (ISO/IEC 14882:2024)
- 20.2.6 显式生命周期管理 [obj.lifetime]
[编辑] 参见
(C++20) |
将一种类型的对象表示重新解释为另一种类型 (函数模板) |
(C++20) |
将 span 转换为其底层字节的视图 (函数模板) |