Template Metaprogrammin(4) - ポリシー

ということで、ポリシーです。ポリシーてのはつまり、テンプレート引数に渡す型(クラス)を切り替えることで対象のクラスの実装にも簡単に変更を加えよう、というものです。説明が難しいのですが、例えば std::stack<> は STL(もしくはstackに必要なコンセプトを兼ね備えている) のコンテナをラップしてスタックを実装しています。ここでいうコンテナとは std::vector や std::deque などを指しますが、これを切り替えることで、内部の動きを変えることができます。実際の stack よりはるかに簡素なものですが、ポリシーを取り入れた stack の例:

//! スタック
// Tがスタックに格納する型、Containerがポリシー
template<class T, class Container>
class stack_sample
{
    Container m_container;
public:
    stack_sample() : m_container() {}

    typename Container::reference top()     { return m_container.back(); }
    void push(const T& value)               { m_container.push_back(value); }
    void pop()                              { m_container.pop_back(); }
};

//! サンプル
void sample()
{
    stack_sample<int, std::vector<int> > stk;
    stk.push(1);
    stk.push(2);
    stk.push(3);
    stk.pop();

    std::cout << stk.top() << endl;
}

このソースでは stack 自体はテンプレート引数に渡されたクラスのインスタンスを用いてスタックの動きを実現していますが、この渡すクラスを変えることでスタックの動き自体を変更することができます。ここで渡すクラスを「ポリシークラス」などと呼びます。スタックに使うポリシークラス(コンテナ)を切り替えることでパフォーマンスの向上を図ったりなどができるということですね。

平易な説明をしようとしてかえってわけわからなくなってしまっている気もしますが、気にしない。次回はこれで「Singletonのインスタンスを生成するポリシー」を作ってみようと思います。また Singleton 。 Singleton だけでご飯三杯はいけてしまいそうです。