名前付き要件: Allocator
オブジェクトのアクセス、アドレス取得、確保、解放、構築、破棄に対する戦略をカプセル化します。
std::string
、 std::vector
、および std::array
を除くすべてコンテナから、 std::shared_ptr
や std::function
まで、記憶域を確保したり解放したりする必要があることがあるすべての標準ライブラリのコンポーネントは Allocator を通してそれを行います。 Allocator は以下の要件を満たすクラス型のオブジェクトです。
いくつかの要件はオプショナルです。 テンプレート std::allocator_traits はすべてのオプショナルな要件に対するデフォルトの実装を提供し、すべての標準ライブラリのコンテナおよびその他のアロケータ対応クラスは直接ではなく std::allocator_traits
を通してアロケータにアクセスします。
目次 |
[編集] 要件
- cv 修飾されていないオブジェクト型
T
-
T
型に対する Allocator 型A
-
A
型のオブジェクトa
- 何らかの cv 修飾されていないオブジェクト型
U
のための (A
を rebind することによって取得された) 対応する Allocator 型B
-
B
型のオブジェクトb
- allocator_traits<A>::allocate() を呼ぶことによって取得された
allocator_traits<A>::pointer
型の値ptr
-
ptr
からの変換によって取得されたallocator_traits<A>::const_pointer
型の値cptr
-
ptr
からの変換によって取得されたallocator_traits<A>::void_pointer
型の値vptr
-
cptr
からの、またはvptr
からの変換によって取得されたallocator_traits<A>::const_void_pointer
型の値cvptr
- 何らかの cv 修飾されていないオブジェクト型
X
への逆参照可能なポインタxptr
- 式 *ptr によって取得された
T
型の左辺値r
-
allocator_traits<A>::size_type
型の値n
が与えられたとき、
式 | 要件 | 戻り値の型 |
---|---|---|
A::pointer (オプション) | NullablePointer、 LegacyRandomAccessIterator および LegacyContiguousIterator を満たす。 (下のファンシーポインタを参照) | |
A::const_pointer (オプション) | A::pointer が A::const_pointer に変換可能である。 NullablePointer、 LegacyRandomAccessIterator および LegacyContiguousIterator を満たす。
|
|
A::void_pointer (オプション) | A::pointer が A::void_pointer に変換可能である。
|
|
A::const_void_pointer (オプション) | A::pointer 、 A::const_pointer および A::void_pointer が A::const_void_pointer に変換可能である。
|
|
A::value_type | 型 T
| |
A::size_type (オプション) | A::size_type が確保可能な最も大きなオブジェクト A のサイ��を表現できる。
|
符号なし整数型 |
A::difference_type (オプション) | A::difference_type が A によって確保されたオブジェクトを指す任意の2つのポインタの差を表現できる。
|
符号付き整数型 |
A::template rebind<U>::other (オプション)[1] | 任意の U について B::template rebind<T>::other が A である。
|
型 B
|
*ptr | T&
| |
*cptr | *cptr と *ptr が同じオブジェクトを識別する。 | const T&
|
ptr->m | (*ptr).m が well-defined であれば、 (*ptr).m と同じ。 | T::m の型
|
cptr->m | (*cptr).m が well-defined であれば、 (*cptr).m と同じ。 | T::m の型
|
static_cast<A::pointer>(vptr) | static_cast<A::pointer>(vptr) == ptr | A::pointer
|
static_cast<A::const_pointer>(cvptr) | static_cast<A::const_pointer>(cvptr) == cptr | A::const_pointer
|
std::pointer_traits<A::pointer>::pointer_to(r) | A::pointer
| |
a.allocate(n) | T 型のオブジェクト n 個のために適した記憶域を確保するが、それらを構築はしない。
例外を投げても構わない。 |
A::pointer
|
a.allocate(n, cvptr) (オプション) | a.allocate(n) と同じであるが、局所性を補助するために cvptr (a.allocate() または nullptr_t から取得したポインタ) を未規定の方法で使用しても構わない。
|
A::pointer
|
a.deallocate(ptr, n) | ptr の指す記憶域を解放する。 ptr は allocate の以前の呼び出しによって返された値でなければならず、 deallocate の呼び出しを挟むことによって無効化されていてはならない。
|
(未使用) |
a.max_size() (オプション) | A::allocate() に渡せる最も大きな値。
|
A::size_type
|
a1 == a2 | アロケータ a1 によって確保された記憶域が a2 を通して解放できる場合にのみ true を返す。 反射律、対称律、推移律を確立する。 例外を投げない。
|
bool |
a1 != a2 | !(a1==a2) と同じ。 | bool |
A a1(a)
A a1 = a |
a1 == a であるような a1 をコピー構築する。 例外を投げない。 (ノート: すべての Allocator は CopyConstructible も満たします)
|
|
A a(b) | B(a)==b かつ A(b)==a であるような a を構築する。 例外を投げない。 (ノート: これは、 rebind によって関係を持つすべてのアロケータがメモリプールなどのお互いのリソースを管理することを暗黙に示します)
|
|
A a1(std::move(a))
A a1 = std::move(a) |
a の以前の値と等しくなるような a1 を構築する。 例外を投げない。 a の値は変更されず、 a1 == a となる。 (C++20以上)
|
|
A a(std::move(b)) | A(b) の以前の値と等しくなるような a を構築する。 例外を投げない。
|
|
a.construct(xptr, args) (オプション) | コンストラクタの引数として args を使用して、 xptr の指すアドレスにある以前に確保された記憶域に X 型のオブジェクトを構築する。
|
|
a.destroy(xptr) (オプション) | xptr の指す X 型のオブジェクトを破棄するが、いかなる記憶域も解放はしない。
|
|
a.select_on_container_copy_construction() (オプション) | 現在 a を使用しているコンテナからコピー構築されたコンテナによって使用されるための A のインスタンスを提供する。 通常、 a のコピーかデフォルト構築された A() のいずれかを返します。
|
A
|
A::propagate_on_container_copy_assignment (オプション) | 型 A のアロケータを使用するコンテナがコピー代入されたときにアロケータをコピーする必要がある場合 true。 ソースコンテナとターゲットコンテナのアロケータが等しくない場合、コピー代入は要素 (およびアロケータ) をコピーする前に古いアロケータを使用してターゲットのメモリを解放し、それから新しいアロケータを使用して確保する必要があることに注意してください。
|
std::true_type または std::false_type またはそれらの派生 |
A::propagate_on_container_move_assignment (オプション) | 型 A のアロケータを使用するコンテナがムーブ代入されたときにアロケータをムーブする必要がある場合 true。 このメンバが false でソースコンテナとターゲットコンテナのアロケータが等しくない場合、ムーブ代入はソースメモリの所有権を取ることはできず、自身のメモリを必要に応じてリサイズし、要素を個別にムーブ代入またはムーブ構築しなければなりません。
|
std::true_type または std::false_type またはそれらの派生 |
A::propagate_on_container_swap (オプション) | 型 A のアロケータを使用するコンテナがスワップされたとき、アロケータをスワップする必要がある場合 true。 このメンバが false で2つのコンテナのアロケータが等しくない場合、コンテナのスワップの動作は未定義です。
|
std::true_type または std::false_type またはそれらの派生 |
A::is_always_equal (C++17以上) (オプション) | 型 A の任意の2つのアロケータが常に等しい場合は true。 提供されない場合、 std::allocator_traits によりデフォルトで std::is_empty<A>::type と等しくなります。
|
std::true_type または std::false_type またはそれらの派生 |
注釈:
- ↑ rebind はこのアロケータが SomeAllocator<T, Args> 形式のテンプレートである場合にのみオプショナルです (std::allocator_traits によって提供されます)。 ただし
Args
はゼロ個以上の追加のテンプレート型引数です。
さらに、型
|
(C++17以上) |
また、
が与えられたとき、 また、
が与えられたとき、式 w1 == w2 および w1 != w2 について、いずれかまたは両方のオブジェクトを意味を変えずに また、
が与えられたとき、式 p1 == p2, p1 != p2, p1 < p2 p1 <= p2, p1 >= p2, p1 > p2, p1 - p2} について、いずれかまたは両方のオブジェクトを意味を変えずに 上の要件により、 Container のイテレータと const_iterator の比較が可能となります。 |
(C++14以上) |
アロケータの完全性の要件型
|
(C++17以上) |
[編集] ファンシーポインタ
メンバ型 pointer
が生のポインタ型でないとき、それは一般的に「ファンシーポインタ」と呼ばれます。 そのようなポインタはセグメント化されたメモリアーキテクチャをサポートするために導入され、今日では生のポインタによってアクセスされる均質な仮想アドレス空間とは異なるアドレス空間に確保されたオブジェクトにアクセスするために使用されます。 ファンシーポインタの例としては、 std::set のようなノードベースのデータ構造を、共有メモリや、各プロセス内の異なるアドレスにマップされたメモリマップドファイルに確保することを可能とする、マップされたアドレスに依存しないポインタ boost::interprocess::offset_ptr があります。 ファンシーポインタは、クラステンプレート std::pointer_traits を通して、それを提供するアロケータとは独立に、使用することができます。
[編集] 標準ライブラリ
以下の標準ライブラリのコンポーネントは Allocator の要件を満たします。
デフォルトのアロケータ (クラステンプレート) | |
(C++11) |
多段コンテナのための多段アロケータを実装します (クラステンプレート) |
(C++17) |
構築時に指定された std::memory_resource をベースとした実行時ポリモーフィズムをサポートするアロケータ (クラステンプレート) |
[編集] 例
C++11 のアロケータ。 ただし C++20 のスタイルにマッチさせるために [[nodiscard]] が追加されています。
#include <cstdlib> #include <new> #include <limits> template <class T> struct Mallocator { typedef T value_type; Mallocator() = default; template <class U> constexpr Mallocator(const Mallocator<U>&) noexcept {} [[nodiscard]] T* allocate(std::size_t n) { if(n > std::numeric_limits<std::size_t>::max() / sizeof(T)) throw std::bad_alloc(); if(auto p = static_cast<T*>(std::malloc(n*sizeof(T)))) return p; throw std::bad_alloc(); } void deallocate(T* p, std::size_t) noexcept { std::free(p); } }; template <class T, class U> bool operator==(const Mallocator<T>&, const Mallocator<U>&) { return true; } template <class T, class U> bool operator!=(const Mallocator<T>&, const Mallocator<U>&) { return false; }