C++ 名前付き要件: AllocatorAwareContainer (C++11 以降)
AllocatorAwareContainer は、Allocator のインスタンスを保持し、そのインスタンスをすべてのメンバ関数で使用してメモリの割り当てと解放、およびそのメモリ内でのオブジェクトの構築と破棄(そのようなオブジェクトはコンテナ要素、ノード、またはハッシュコンテナの場合はバケット配列である可能性があります)を行うContainer です。ただし、std::basic_string の特殊化は、要素の構築/破棄にアロケータを使用しません(C++23 以降)。
コンテナ構築には以下の規則が適用されます。
- AllocatorAwareContainer のコピーコンストラクタは、コピー元のコンテナのアロケータに対して std::allocator_traits<allocator_type>::select_on_container_copy_construction を呼び出すことによってアロケータのインスタンスを取得します。
- ムーブコンストラクタは、古いコンテナに属するアロケータからムーブ構築することによってアロケータのインスタンスを取得します。
- その他のすべてのコンストラクタは、const allocator_type& パラメータを受け取ります。
アロケータを置き換える唯一の方法は、コピー代入、ムーブ代入、および swap です。
- コピー代入は、std::allocator_traits<allocator_type>::propagate_on_container_copy_assignment::value が true の場合にのみアロケータを置き換えます。
- ムーブ代入は、std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::value が true の場合にのみアロケータを置き換えます。
- Swap は、std::allocator_traits<allocator_type>::propagate_on_container_swap::value が true の場合にのみアロケータを置き換えます。具体的には、非修飾の非メンバ関数 swap の呼び出しを通じてアロケータのインスタンスを交換します。詳細は Swappable を参照してください。
注意: propagate_on_container_swap が false の場合、アロケータが異なる 2 つのコンテナを swap する際の動作は未定義です。
- アクセサ
get_allocator()は、コンテナの構築に使用された、または直近のアロケータ置換操作によってインストールされたアロケータのコピーを取得します。
目次 |
[編集] 要件
型は Container を満たし、かつ、以下の型と値が与えられた場合に、以下の表のセマンティック要件と複雑性要件を満たす場合、AllocatorAwareContainer を満たします。
| 型 | 定義 |
X
|
AllocatorAwareContainer 型 |
T
|
X の value_type |
A
|
X によって使用されるアロケータ型 |
| 値 | 定義 |
| a, b | X の非 const 左辺値 |
| c | const X の左辺値 |
| t | X の左辺値または const 右辺値 |
| rv | X の非 const 右辺値 |
| m | A の値 |
[編集] 型
| 名前 | 型 | 要件 |
|---|---|---|
| typename X::allocator_type | A
|
X::allocator_type::value_type と X::value_type は同じです。 |
[編集] ステートメント
| ステートメント | セマンティクス | 計算量 | |
|---|---|---|---|
| X u; X u = X(); |
事前条件 | A は DefaultConstructible です。 |
Constant |
| 事後条件 | u.empty() および u.get_allocator() == A() は両方とも true です。 | ||
| X u(m); | 事後条件 | u.empty() および u.get_allocator() == m は両方とも true です。 | Constant |
| X u(t, m); | 事前条件 | T は X に CopyInsertable です。 |
線形 |
| 事後条件 | u == t および u.get_allocator() == m は両方とも true です。 | ||
| X u(rv); | 事後条件 |
|
Constant |
| X u(rv, m); | 事前条件 | T は X に MoveInsertable です。 |
|
| 事後条件 |
| ||
[編集] 式
| Expression | 型 | セマンティクス | 計算量 | |
|---|---|---|---|---|
| c.get_allocator() | A
|
直接的なセマンティック要件はありません。 | Constant | |
| a = t | X&
|
事前条件 | T は X に CopyInsertable であり、CopyAssignable です。 |
線形 |
| 事後条件 | a == t は true です。 | |||
| a = rv | X&
|
事前条件 | アロケータがムーブ代入によって置き換えられない場合(上記を参照)、T は X に MoveInsertable であり、MoveAssignable です。 |
線形 |
| 効果 | a の既存のすべての要素は、ムーブ代入されるか破棄されます。 | |||
| 事後条件 | a と rv が同じオブジェクトを参照しない場合、代入前の rv の値に a は等しくなります。 | |||
| a.swap(b) | void | 効果 | a と b の内容を交換します。 |
Constant |
[編集] 注意
AllocatorAwareContainer は、型 T のオブジェクトを p の位置に args を使用して構築するために、常に std::allocator_traits<A>::construct(m, p, args) を呼び出します。ここで m == get_allocator() です。std::allocator のデフォルトの construct は ::new((void*)p) T(args) を呼び出しますが(C++20 まで)std::allocator には construct メンバがなく、要素の構築時には std::construct_at(p, args) が呼び出されます(C++20 以降)。ただし、特殊化されたアロケータは異なる定義を選択する場合があります。
[編集] 標準ライブラリ
すべての標準ライブラリの文字列型とコンテナ(std::array と std::inplace_vector を除く)は AllocatorAwareContainer です。
| 文字のシーケンスを格納し操作する (クラステンプレート) | |
| 両端キュー (クラステンプレート) | |
| (C++11) |
単方向連結リスト (クラステンプレート) |
| 双方向リンクリスト (クラステンプレート) | |
| リサイズ可能な連続配列 (クラステンプレート) | |
| キーでソートされたキーと値のペアのコレクション、キーは一意 (クラステンプレート) | |
| キーによってソートされたキーと値のペアのコレクション (クラステンプレート) | |
| ユニークなキーのコレクション、キーによってソートされる (class template) | |
| キーによってソートされたキーのコレクション (クラステンプレート) | |
| (C++11) |
キーによってハッシュ化されたキーと値のペアのコレクション、キーはユニーク (クラステンプレート) |
| (C++11) |
キーでハッシュ化されたキーと値のペアのコレクション (クラステンプレート) |
| (C++11) |
キーによってハッシュ化されたユニークなキーのコレクション (クラステンプレート) |
| (C++11) |
キーのコレクション、キーによってハッシュ化される (class template) |
[編集] 欠陥報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| LWG 2839 | C++11 | 標準コンテナの自己ムーブ代入が許可されていなかった | 許可されたが、結果は未指定 |