std::start_lifetime_as, std::start_lifetime_as_array
From cppreference.com
| ヘッダ <memory> で定義 |
||
std::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から) |
std::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 の場合、U が「n 個の T の配列」である型である std::start_lifetime_as<U>(p) と等価です。それ以外の場合、関数は何も効果がありません。-
Tは完全な型でなければなりません。そうでなければ、プログラムは不正です。 - 以下の場合、動作は未定義です:
- null でない p が
Tの配列に適切にアラインされていない場合、または - n <= std::size_t(-1) / sizeof(T) が false の場合、または
- n > 0 であり、かつ
[(char*)p,(char*)p + (n * sizeof(T)))が、p を介して到達可能なストレージ領域のサブセットである割り当て済みストレージ領域を指していない場合。
- null でない 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 をその基になるバイトのビューに変換します(関数テンプレート) |