2相テンプレートの利点は、クラステンプレートの実体化を2段階に分割して行えることである。この特長は、ポリシークラスにおいて特に有効である。以下の例は、記憶領域割り当てポリシーの実装に2相テンプレートを用いたものである。
例 5.6. 2相テンプレートを用いたポリシークラス
template <typename T>
class allocation_policy_new_backend
{
protected:
void* allocate() { return ::operator new(sizeof(T)); }
void deallocate(void* p) throw() { ::operator delete(p); }
};
struct allocation_policy_new
{
template <typename T>
struct bind { typedef allocation_policy_new_backend<T> type; };
};
template <typename T, class AP>
class container
: public AP::template bind<T>::type
{
private:
typedef typename AP::template bind<T>::type allocation_policy;
using allocation_policy::allocate;
using allocation_policy::deallocate;
public:
container()
: allocation_policy() {}
container(const container& rhs)
: allocation_policy(rhs) {}
// ...
};
void foo()
{
typedef int T;
typedef allocation_policy_new AP;
container<T, AP> C;
// ...
}
割り当てポリシーは、フロントエンドallocation_policy_newとバックエンドallocation_policy_new_backendで構成される。
ホストクラスcontainerは、第2テンプレートパラメータAPに割り当てポリシーのフロントエンドを取る。実装コード内ではAPそのものではなく、APにパラメータTを与えることで得たバックエンドを用いる。
AP::template bind<T>::type
クライアントコードfooは、ホストクラスcontainerにポリシークラスのフロントエンドallocation_policy_newを与えて用いる。ポリシークラスが2相テンプレートを用いていることを特に意識する必要はない。