CRTPの勉強

先日CRTP(Curiously Recursive Template Pattern)の勉強をしたので,それのメモ.

CRTPとは,基底クラスをクラステンプレートとして定義して,派生クラスでは,その基底クラスのテンプレート引数部分に自分自身を突っ込むものです.

基底クラス内で,派生クラスの型へキャストでき,派生クラスのみで定義した関数を呼び出せるのがポイント.

あとは,コード中に書いたコメント参照.

#include <iostream>
template <typename Inherited>
struct Base{
void apply(){
// Inheriedにダウンキャストし,そこで定義されているはずのapply_impl()を呼び出す
static_cast<Inherited&>(*this).apply_impl();
}
void test(){
std::cout << "Base" << std::endl;
}
};
struct Inherit1: public Base<Inherit1>{
void apply_impl(){
std::cout << "Inherit 1" << std::endl;
}
};
struct Inherit2: public Base<Inherit2>{
void apply_impl(){
std::cout << "Inherit 2" << std::endl;
}
};
// Baseの派生クラスのみを受け取る関数
template<typename T>
void check(Base<T>& t){
// ポイント1:ここには,Base<T>のサブクラスのインスタンスしかこない(t.test()が呼べる)
// ポイント2:Base<T>のサブクラスにapply_impl()が定義されてないとコンパイルエラー
// ポイント3:tのapply()は多態的に呼び出される
// ポイント4:仮想関数ではないため呼出しにオーバーヘッドがない
t.apply();
t.test();
}
int main(){
Inherit1 inh1;
Inherit2 inh2;
check(inh1);
check(inh2);
}

“CRTPの勉強” への1件の返信

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です