C++11では、ユーザー定義のアロケータが状態を持てるようになりました。それにともなって、コンテナのコピー、ムーブ、swap時に、アロケータの状態を伝搬するかどうかを制御できるようになりました。
コピー代入、ムーブ代入、swapの伝搬を制御
アロケータの状態を伝搬するには、ユーザー定義アロケータに、以下のメンバ型を定義します。
propagate_on_container_copy_assignment
: コンテナのコピー代入時に状態を伝搬する。propagate_on_container_move_assignment
: コンテナのムーブ代入時に状態を伝搬する。propagate_on_container_swap
: コンテナのswap時に状態を伝搬する。
これらのメンバ型を、<type_traits>
ヘッダで定義されるstd::true_type
の別名として定義すれば、コンテナの各ポイントで、アロケータの状態が伝搬されるようになります。
これらのメンバ型を定義しない場合は、アロケータの状態は伝搬されません。
C++11のstd::allocator
はこれらのメンバ型を定義していません。
C++14では、謎の日本人Ai Azumaさんの提案によって、std::allocator
に以下のメンバ型が定義されるようになります。
typedef std::true_type propagate_on_container_move_assignment;
つまり、コンテナのムーブ代入時に、std::allocator
オブジェクトの状態が自動的にムーブ先に伝搬されるようになります。
コピー構築に使用するアロケータオブジェクトを選択
また、状態を伝搬するメンバ型に加えて、コピー構築に使用するコンテナを選択する関数もあります。ユーザー定義のアロケータに、以下のpublic
メンバ関数を定義します。
MyAllocatorType select_on_container_copy_construction() const;
これを定義すれば、コンテナのコピー構築時に、自身のアロケータをそのまま使うか、あるいは新たなアロケータオブジェクトを作るのかを選択できます。この関数を定義しない場合は、コピー元コンテナが持つアロケータのコピーを使用します。