std::allocate_shared, std::allocate_shared_for_overwrite
ヘッダ <memory> で定義 | ||
template<class T, class Alloc, class... Args> shared_ptr<T> allocate_shared(const Alloc& alloc, Args&&... args); | (1) | (C++11以上) (T is non-array) |
template<class T, class Alloc > shared_ptr<T> allocate_shared(const Alloc& alloc, std::size_t N ); | (2) | (C++20以上) (T is U[]) |
template<class T, class Alloc > shared_ptr<T> allocate_shared(const Alloc& alloc ); | (3) | (C++20以上) (T is U[N]) |
template<class T, class Alloc > shared_ptr<T> allocate_shared(const Alloc& alloc, std::size_t N, | (4) | (C++20以上) (T is U[]) |
template<class T, class Alloc > shared_ptr<T> allocate_shared(const Alloc& alloc, | (5) | (C++20以上) (T is U[N]) |
template<class T, class Alloc > shared_ptr<T> allocate_shared_for_overwrite(const Alloc& alloc ); | (6) | (C++20以上) (T is not U[]) |
template<class T, class Alloc > shared_ptr<T> allocate_shared_for_overwrite(const Alloc& alloc, std::size_t N ); | (7) | (C++20以上) (T is U[]) |
args
を T
のコンストラクタに対する引数リストとして使用して T
型のオブジェクトを構築し、それを std::shared_ptr にラップします。 オブジェクトは式 ::new(pv) T(v)(C++20未満)std::allocator_traits<A2>::construct(a, pv, v)(C++20以上) を用いたかのように構築されます。 ただし pv
は T
型のオブジェクトを保持するのに適した記憶域を指す内部的な void*
ポインタで、 a
は std::remove_cv_t<T> に再束縛されたアロケータのコピーです。 記憶域は、一般的には、 shared_ptr の制御ブロックと T
オブジェクトの両方に対して1回で確保を行うため、 sizeof(T)
より大きくなります。 この関数によって呼ばれる std::shared_ptr
のコンストラクタは、 T
型の新たに構築されたオブジェクトを指すポインタで shared_from_this
を有効化します。 すべてのメモリ確保は alloc のコピーを使用して行われます。 alloc は Allocator の要件を満たさなければなりません。 このオーバーロードは、T が配列型でない場合にのみ、オーバーロード解決に参加します。A2
型の a2
は、 std::remove_cv_t<std::remove_all_extents_t<T>> 型のオブジェクトを管理するために再束縛されたアロケータのコピーです。 オーバーロード (2) は、最初の次元のサイズが N
の配列を作成します。 配列要素はそのアドレスの昇順に初期化され、生存期間を終えるときはその逆の順序で破棄されます。u
から初期化されます。 std::remove_extent_t<T> がそれ自身配列型でなければ、これは (1) の場合と同じアロケータの式で行われたかのように行われます。 ただしアロケータは std::remove_cv_t<std::remove_all_extents_t<T>> に再束縛されます。 そうでなければ、これは配列 (多次元かもしれない) のすべての非配列要素が (1) の場合と同じアロケータの式で u
内の対応する要素から初期化されたかのように行われます。 ただしアロケータは型 std::remove_cv_t<std::remove_all_extents_t<T>> に再束縛されます。 オーバーロード (4) は、最初の次元のサイズが N
の配列を作成します。 配列要素はそのアドレスの昇順に初期化され、生存期間を終えるときはその逆順で破棄されます。allocate_shared
の場合、オブジェクト (または (2-5) の場合は個々の配列要素)(C++20以上) は、式 std::allocator_traits<A2>::destroy(a, p) を通して破棄されます。 ただし p
はオブジェクトを指すポインタで a
は allocate_shared に渡されたアロケータの破棄するオブジェクトの型に再束縛されたコピーです。
| (C++20以上) |
目次 |
[編集]引数
alloc | - | 使用する Allocator |
args... | - | T のインスタンスを構築するための引数リスト |
N | - | 使用する配列サイズ |
u | - | 配列のすべての要素を初期化するための初期値 |
[編集]戻り値
T
型のインスタンスの std::shared_ptr。
[編集]例外
Alloc::allocate() または T
のコンストラクタから投げられる例外を投げる可能性があります。 例外が投げられた場合、 (1) は効果を持ちません。 配列の構築中に例外が投げられた場合、すでに初期化された要素は逆順で破棄されます。(C++20以上)
[編集]ノート
std::make_shared と同様、この関数は一般的には1回しか確保を行わず、その確保したメモリブロックに T
のオブジェクトと制御ブロックの両方を置きます。 (標準はそのように推奨していますが、要求はしていません。 すべての既知の実装はそれを行っています。) alloc
のコピーは、 shared_ptr と weak_ptr 両方の参照カウントがゼロに達したとき、それを解放するために使用できるように、制御ブロックの一部として格納されます。
std::shared_ptr のコンストラクタと異なり、 std::allocate_shared は別個のカスタムデリータを受け取りません。 制御ブロックと T
のオブジェクトの破棄、およびそれらの共有されたメモリブロックの解放のためには、供給されたアロケータが使用されます。
std::shared_ptr は (C++17以降) 配列型をサポートしますが、 | (C++20未満) |
コンストラクタが U*
型のポインタ ptr
で shared_from_this
を有効化するとは、 U
が曖昧でなくアクセス可能な(C++17以上)std::enable_shared_from_this の特殊化を基底クラスに持つかどうか調べ、もし持つのであれば以下の文を評価する、という意味です。
if(ptr != nullptr && ptr->weak_this.expired()) ptr->weak_this =std::shared_ptr<std::remove_cv_t<U>>(*this, const_cast<std::remove_cv_t<U>*>(ptr));
ただし weak_this
は std::shared_from_this が持つ std::weak_ptr
型の隠された mutable なメンバです。 weak_this
メンバの代入はアトミックでなく、同じオブジェクトに対するあらゆる潜在的な並行アクセスと衝突します。 これにより shared_from_this() の将来の呼び出しが、この生のポインタのコンストラクタによって作成された shared_ptr
と、所有権を共有することが保証されます。
上記の説明用コード内の判定 ptr->weak_this.expired()
は、すでに所有者がある場合に weak_this
が再代入されないようにします。 C++17 以降この判定が要求されます。
[編集]関連項目
新しい shared_ptr を構築します (パブリックメンバ関数) | |
新しいオブジェクトを管理する shared_ptr を作成します (関数テンプレート) |