namespace std {
template<class T, class A>
shared_ptr<T>
allocate_shared_for_overwrite(const A& a); // (1) C++20
template<class T, class A>
constexpr shared_ptr<T>
allocate_shared_for_overwrite(const A& a); // (1) C++26
template<class T, class A>
shared_ptr<T>
allocate_shared_for_overwrite(const A& a, size_t N); // (2) C++20
template<class T, class A>
constexpr shared_ptr<T>
allocate_shared_for_overwrite(const A& a, size_t N); // (2) C++26
}
概要
T型のオブジェクト、またはその配列へのshared_ptrを構築し、返却する。
要件
テンプレートパラメータAはCpp17Allocatorの要件を満たす。
効果
型Tのオブジェクトにメモリを割り当てる(TがU[]の場合はU[N]。Nはそれぞれのオーバーロードで指定された引数から決定される)。メモリは、引数aのコピー(参照カウンタと型Tの本体を連続メモリ領域に配置するためにはTのサイズより大きい領域をアロケートする必要があるためにallocator_traits<Alloc>::rebind_alloc<value_type>を用いて再束縛されたもの)を使用して割り当てられる。
すべてのオーバーロードにおいて、確保された領域のオブジェクトはデフォルト構築される。
例外がスローされた場合、関数は効果がない。
非配列型Uの(サブ)オブジェクトがこの関数によって初期化されるときは、式::new(pv) Uによって初期化される。ここで、pvは型 void *を持ち、型Uのオブジェクトを保持するための適切なストレージを指す。
配列要素は、アドレスの昇順で初期化される。
戻り値によって管理されるオブジェクトのlifetimeが終了するか、配列要素の初期化が例外をスローすると、初期化された要素は元の構造の逆の順序で破棄される。
- (1) : このオーバーロードが選択されるとき、
Tは、不明な境界の配列ではない。T型のオブジェクトへのshared_ptrを返す。 - (2) : このオーバーロードが選択されるとき、
Tは、不明な境界の配列である。型U[N]のオブジェクトへのshared_ptrを返す。ここで、Uはremove_extent_t<T>である。
戻り値
新しく構築されたオブジェクトのアドレスを格納および所有するshared_ptrインスタンス。
事後条件
r.get() != 0 && r.use_count() == 1, ここで、r は戻り値である。
例外
bad_alloc、またはallocateまたはオブジェクトの初期化からスローされた例外。
備考
同様の効果を持つ関数に、make_shared_for_overwrite()があるが、
この関数はメモリの確保にユーザー定義のアロケータを使用したい場合などに用いることができる。
デフォルト構築においては、トリビアルにデフォルト構築可能な型のオブジェクトは未初期化状態となるため、値を読みだす前に明示的に初期化(overwrite)する必要がある。初期化後の状態が不定になってほしくない場合はこの関数ではなくallocate_shared()を使用すべき。
例
#include <memory>
#include <iostream>
int main() {
std::allocator<int> alloc;
std::shared_ptr<int> sp = std::allocate_shared_for_overwrite<int>(alloc);
if (sp) {
*sp = 0; // 必ず初期化する
std::cout << *sp << std::endl;
}
}
出力
0
バージョン
言語
- C++20
処理系
- Clang: 10.0.0 現在未対応 ✅
- GCC: 10.0.0 現在未対応 ✅
- Visual C++: ??