へんてこりんに再帰したテンプレートパターン

C++のCRTP(Curiously Recurring Template Pattern)の話。

CRTPでは継承クラスの関数を使って基底クラスの関数を実装することができる。

#include <iostream>

template<class T>
class base
{
	const T& get_this() const
	{
		return static_cast<const T&>(*this);
	}

	void p_impl() const
	{
		std::cout << "template<class> class base\n";
	}

public:
	void print() const
	{
		this->p_impl();
		this->get_this().p_impl();
	}
};

class derived : public base<derived>
{
	void p_impl() const
	{
		std::cout << "class derived\n";
	}

	friend class base<derived>;
};

class derived2 : public base<derived2>
{
};

int main(int, char**)
{
	derived().print();
	derived2().print();

	return 0;
};

class derivedのp_impl関数を使ってclass baseのprint関数を実装できるが、上記ソースコードのように基底クラスにp_implを用意しておけばderived2ではp_impl関数が無くても基底クラスのp_implが呼ばれる。

実行結果

template class base
class derived
template class base
template class base

当たり前のことかもしれないけど、CRTPでこのように基底クラスに関数のデフォルト実装を書いておくことができるというのを今日知った。