CRTP (Curiously Recurring Template Pattern)の使い方

CRTPというC++で使われるテクニックがある。これは自分自身をテンプレートパラメータとしたテンプレートから派生してクラスを定義するものだ。これはこちらのページに詳しいが、今回はCRTPのもっとも便利だと思われる使い方を示してみようと思う。
CRTPを具体例は、以下のようだ。

template<class T> class CRTP_base{};

class A;//前宣言
class A:public CRTP_base<A>{
    //省略・・・メンバいろいろ・・・
};

さあこれがなんの役に立つのか?・・・これは静的ポリモーフィズムを実現するのに役立つ。
たとえばクラスAとBがあり、これらが同じインターフェース(メンバ関数郡)をもたせ、これらを同様に扱いたいながらも異なる動作をさせたい。こんな時、普通は動的ポリモーフィズムを使う。例えば下のように。

class base{//インターフェース用基底クラス
public:
    virtual void method_A() = 0;//仮想関数
    virtual void method_B() = 0;//仮想関数
    //仮想関数他にもいろいろ
};

class A:public base{
public
    void method_A(){  /*実装*/  }
    void method_B(){  /*実装*/  }
    //他にもいろいろ実装
};

class B:public base{
public
    void method_A(){  /*実装*/  }
    void method_B(){  /*実装*/  }
    //他にもいろいろ実装
};

void function_p(base * p){//ポインタ版
    //baseを継承したクラスのインスタンスのメンバを呼び出す。
}

void function_r(base & r){//参照版
    //baseを継承したクラスのインスタンスのメンバを呼び出す。
}
//
int main(){
    base *bp;
    bp = new A();function_p(bp); delete bp;//Aのインスタンスを使う。
    bp = new B();function_p(bp); delete bp;//Bのインスタンスを使う。    
    function_r( A() );//Aのインスタンスを使う。
    function_r( B() );//Bのインスタンスを使う。
}

しかしながらこの方法はオブジェクトを返すような関数には、うまくいかない。例えばオブジェクトを足し算して返すよな関数だ。

返り値の型 plus(const base& lhs, const base & rhs){
    //get_value() は足し算に必要なメンバであるとする。
    return 返り値の型(lhs.get_value() + rhs.get_value());//何を返せばいい?返り値の型はbaseじゃないよね。 
}

そこでCRTPをつかった静的なポリモーフィズム(実際には単なるオーバーロード)の出番となる。

template<class T> class CRTP_base{};

class A;class B;//前宣言
class A:public CRTP_base<A>{
    //get_value()  
    //省略
};
class B:public CRTP_base<B>{
    //get_value()  
    //省略
};

template
T plus(const CRTP_base & lhs, const CRTP_base & rhs){
    return T(static_cast(lhs).get_value() + static_cast(rhs).get_value() );//get_value() は足し算に必要なメンバであるとする。
}

以上でクラスAおよびBに対して足し算関数が定義できた。
CRTPを使えば、同じインターフェースを持つクラスに対する関数を定義できる(可能になるというよりテンプレートに対し制限することができると言ったほうがいいだろう)。