std::allocator
| ヘッダ <memory> で定義 |
||
| template< class T > struct allocator; |
(1) | |
| template<> struct allocator<void>; |
(2) | (C++17で非推奨) (C++20で削除) |
std::allocator クラステンプレートは、ユーザー指定のアロケーターが提供されない場合に、すべての標準ライブラリコンテナで使用されるデフォルトの Allocator です。デフォルトのアロケーターはステートレスです。つまり、指定されたアロケーターのすべてのインスタンスは交換可能であり、等しいと比較され、同じアロケーター型の他のインスタンスによって割り当てられたメモリを解放できます。
|
void の明示的な特殊化には、メンバ typedef |
(C++20まで) |
|
デフォルトのアロケーターはアロケーターの完全性要件を満たします。 |
(C++17以降) |
目次 |
[編集] メンバ型
| 型 | 定義 |
value_type
|
T
|
pointer (C++17で非推奨)(C++20で削除) |
T*
|
const_pointer (C++17で非推奨)(C++20で削除) |
const T* |
reference (C++17で非推奨)(C++20で削除) |
T&
|
const_reference (C++17で非推奨)(C++20で削除) |
const T& |
size_type
|
std::size_t |
difference_type
|
std::ptrdiff_t |
propagate_on_container_move_assignment (C++11) |
std::true_type |
rebind (C++17で非推奨)(C++20で削除) |
template< class U > struct rebind |
is_always_equal (C++11)(C++23で非推奨)(C++26で削除) |
std::true_type |
[編集] メンバ関数
| 新しいアロケーターインスタンスを作成する (public メンバ関数) | |
| アロケーターインスタンスを破棄する (public メンバ関数) | |
| (C++20まで) |
operator& がオーバーロードされていても、オブジェクトのアドレスを取得する (public メンバ関数) |
| 未初期化のストレージを割り当てる (public メンバ関数) | |
| (C++23) |
要求されたサイズ以上の未初期化ストレージを割り当てる (public メンバ関数) |
| ストレージを解放する (public メンバ関数) | |
| (C++20まで) |
サポートされている最大アロケーションサイズを返す (public メンバ関数) |
| (C++20まで) |
割り当てられたストレージにオブジェクトを構築する (public メンバ関数) |
| (C++20まで) |
割り当てられたストレージにあるオブジェクトを破棄する (public メンバ関数) |
[編集] 非メンバ関数
| (C++20で削除) |
2つのアロケーターインスタンスを比較する (public メンバ関数) |
[編集] 備考
メンバクラステンプレート rebind は、異なる型のアロケーターを取得する方法を提供します。例えば、std::list<T, A> は、内部型 Node<T> のノードを、A::rebind<Node<T>>::other(C++11まで)std::allocator_traits<A>::rebind_alloc<Node<T>> (Aがstd::allocatorの場合、これはA::rebind<Node<T>>::otherとして実装される)(C++11から) を使用して割り当てます。
メンバ型 is_always_equal は、LWG issue 3170 によって非推奨となりました。これは、std::allocator から派生したカスタムアロケーターがデフォルトで常に等しいと扱われるためです。std::allocator_traits<std::allocator<T>>::is_always_equal は非推奨ではなく、そのメンバ定数 value は任意の T に対してtrueです。
[編集] 例
#include <iostream> #include <memory> #include <string> int main() { // default allocator for ints std::allocator<int> alloc1; // demonstrating the few directly usable members static_assert(std::is_same_v<int, decltype(alloc1)::value_type>); int* p1 = alloc1.allocate(1); // space for one int alloc1.deallocate(p1, 1); // and it is gone // Even those can be used through traits though, so no need using traits_t1 = std::allocator_traits<decltype(alloc1)>; // The matching trait p1 = traits_t1::allocate(alloc1, 1); traits_t1::construct(alloc1, p1, 7); // construct the int std::cout << *p1 << '\n'; traits_t1::deallocate(alloc1, p1, 1); // deallocate space for one int // default allocator for strings std::allocator<std::string> alloc2; // matching traits using traits_t2 = std::allocator_traits<decltype(alloc2)>; // Rebinding the allocator using the trait for strings gets the same type traits_t2::rebind_alloc<std::string> alloc_ = alloc2; std::string* p2 = traits_t2::allocate(alloc2, 2); // space for 2 strings traits_t2::construct(alloc2, p2, "foo"); traits_t2::construct(alloc2, p2 + 1, "bar"); std::cout << p2[0] << ' ' << p2[1] << '\n'; traits_t2::destroy(alloc2, p2 + 1); traits_t2::destroy(alloc2, p2); traits_t2::deallocate(alloc2, p2, 2); }
出力
7 foo bar
[編集] 欠陥報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| LWG 2103 | C++11 | allocator間の冗長な比較が必要となる可能性がある |
propagate_on_container_move_assignmentが提供された |
| LWG 2108 | C++11 | allocatorがステートレスであることを示す方法がなかった |
is_always_equalが提供された |
[編集] 関連項目
| (C++11) |
アロケータ型に関する情報を提供します (クラステンプレート) |
| (C++11) |
多階層コンテナのための多階層アロケータを実装します (クラステンプレート) |
| (C++11) |
指定された型が uses-allocator 構築をサポートしているかどうかをチェックします (クラステンプレート) |