std::construct_at
From cppreference.com
| ヘッダ <memory> で定義 |
||
| template< class T, class... Args > constexpr T* construct_at( T* location, Args&&... args ); |
(C++20以降) | |
指定されたアドレスlocationに、argsで指定された引数を使用してTオブジェクトを構築します。
if constexpr (std::is_array_v<T>)
return ::new (voidify (*location)) T[1]();
else
return ::new (voidify (*location)) T(std::forward<Args>(args)...); と同等ですが、construct_atは定数式の評価内で使用できる場合があります。
定数式exprの評価中にconstruct_atが呼び出された場合、locationはstd::allocator<T>::allocateによって取得されたストレージ、またはexprの評価内でライフタイムが開始されたオブジェクトのいずれかを指している必要があります。
このオーバーロードは、以下のすべての条件が満たされた場合にのみオーバーロード解決に参加する。
- std::is_unbounded_array_v<T>はfalseです。
- ::new(std::declval<void*>()) T(std::declval<Args>()...)は、評価されないオペランドとして扱われる場合、well-formedです。
もしstd::is_array_v<T>がtrueで、かつsizeof...(Args)がゼロより大きい場合、プログラムはill-formedとなります。
目次 |
[編集] パラメータ
| location | - | T オブジェクトが構築される未初期化ストレージへのポインタ。 |
| args... | - | 初期化に使用される引数 |
[編集] 戻り値
location
[編集] 例
このコードを実行
#include <bit> #include <memory> class S { int x_; float y_; double z_; public: constexpr S(int x, float y, double z) : x_{x}, y_{y}, z_{z} {} [[nodiscard("no side-effects!")]] constexpr bool operator==(const S&) const noexcept = default; }; consteval bool test() { alignas(S) unsigned char storage[sizeof(S)]{}; S uninitialized = std::bit_cast<S>(storage); std::destroy_at(&uninitialized); S* ptr = std::construct_at(std::addressof(uninitialized), 42, 2.71f, 3.14); const bool res{*ptr == S{42, 2.71f, 3.14}}; std::destroy_at(ptr); return res; } static_assert(test()); int main() {}
[編集] 不具合報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| LWG 3436 | C++20 | construct_atは配列型のオブジェクトを構築できなかった |
bounded arrayのvalue-initializeが可能 |
| LWG 3870 | C++20 | construct_atはcv修飾型のオブジェクトを構築できた |
cv-unqualified型のみが許可される |
[編集] 関連項目
| 未初期化のストレージを割り当てる ( std::allocator<T> の public メンバー関数) | |
| [static] |
割り当てられたストレージにオブジェクトを構築する (関数テンプレート) |
| (C++17) |
与えられたアドレスのオブジェクトを破棄します (関数テンプレート) |
| (C++20) |
与えられたアドレスにオブジェクトを作成します (アルゴリズム関数オブジェクト) |