アロケータ状態の伝搬を制御する

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;

これを定義すれば、コンテナのコピー構築時に、自身のアロケータをそのまま使うか、あるいは新たなアロケータオブジェクトを作るのかを選択できます。この関数を定義しない場合は、コピー元コンテナが持つアロケータのコピーを使用します。

参照