名前空間
変種
操作

std::allocate_shared

提供: cppreference.com
< cpp‎ | memory‎ | shared ptr
 
 
 
動的メモリ管理
未初期化記憶域
(C++17)
ガベージコレクションサポート
その他
(C++20)
(C++11)
(C++11)
C のライブラリ
低水準のメモリ管理
 
 
ヘッダ <memory> で定義
template< class T, class Alloc, class... Args >
shared_ptr<T> allocate_shared( const Alloc& alloc, Args&&... args );
(1) (C++11およびそれ以降)
(T が配列でない場合)
template<class T, class A>
shared_ptr<T> allocate_shared(const A& a, std::size_t N);
(2) (C++20およびそれ以降)
(T が U[] の場合)
template<class T, class A>
shared_ptr<T> allocate_shared(const A& a);
(3) (C++20およびそれ以降)
(T が U[N] の場合)
template<class T, class A>

shared_ptr<T> allocate_shared(const A& a, std::size_t N,

                              const std::remove_extent_t<T>& u);
(4) (C++20およびそれ以降)
(T が U[] の場合)
template<class T, class A>

shared_ptr<T> allocate_shared(const A& a,

                              const std::remove_extent_t<T>& u);
(5) (C++20およびそれ以降)
(T が U[N] の場合)
1) argsT のコンストラクタに対する引数リストとして使用して T 型のオブジェクトを構築し、それを std::shared_ptr にラップします。 オブジェクトは式 std::allocator_traits<A2>::construct(a, pv, v) を用いたかのように構築されます。 ただし pvT 型のオブジェクトを保持するのに適した記憶域を指す内部的な void* ポインタで、 astd::remove_cv_t<T> に再束縛されたアロケータのコピーです。 記憶域は、一般的には、 shared_ptr の制御ブロックと T オブジェクトの両方に対して1回で確保を行うため、 sizeof(T) より大きくなります。 この関数によって呼ばれる std::shared_ptr のコンストラクタは、 T 型の新たに構築されたオブジェクトを指すポインタで shared_from_this を有効化します。 すべてのメモリ確保は alloc のコピーを使用して行われます。 allocAllocator の要件を満たさなければなりません。 このオーバーロードは、T が配列型でない場合にのみ、オーバーロード解決に参加します。
2,3) (1) と同じですが、構築されるオブジェクトは配列 (多次元かもしれない) であり、その std::remove_all_extents_t<T> 型の非配列要素は式 std::allocator_traits<A2>::construct(a2, pv) によって行われたかのように値初期化されます。 ただし A2 型の a2 は、 std::remove_cv_t<std::remove_all_extents_t<T>> 型のオブジェクトを管理するために再束縛されたアロケータのコピーです。 オーバーロード (2) は、最初の次元のサイズが N の配列を作成します。 配列要素はそのアドレスの昇順に初期化され、生存期間を終えるときはその逆の順序で破棄されます。
4,5) (2,3) と同じですが、すべての要素はデフォルト値 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 の配列を作成します。 配列要素はそのアドレスの昇順に初期化され、生存期間を終えるときはその逆順で破棄されます。

目次

[編集] 引数

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以降) 配列型をサポートしますが、 std::allocate_shared はしません。 この機能は boost::allocate_shared ではサポートされています。

(C++20以前)

コンストラクタが U* 型のポインタ ptrshared_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_thisstd::shared_from_this が持つ std::weak_ptr 型の隠された mutable なメンバです。 weak_this メンバの代入はアトミックでなく、同じオブジェクトに対するあらゆる潜在的な並行アクセスと衝突します。 これにより shared_from_this() の将来の呼び出しが、この生のポインタのコンストラクタによって作成された shared_ptr と、所有権を共有することが保証されます。

上記の説明用コード内の判定 ptr->weak_this.expired() は、すでに所有者がある場合に weak_this が再代入されないようにします。 C++17 以降この判定が要求されます。

[編集] 欠陥報告

以下の動作変更欠陥報告は以前に発行された C++ 標準に遡って適用されました。

DR 適用先 発行時の動作 正しい動作
LWG 3007 allocate_shared may (incorrectly) rebind allocator to cv-qualified type remove cv-qualifiers before rebind

[編集] 関連項目

新しい shared_ptr を構築します
(パブリックメンバ関数) [edit]
新しいオブジェクトを管理する shared_ptr を作成します
(関数テンプレート) [edit]