私がCRTPを最初に知ったころは「CRTPを使って静的多相性が出来る!」と思っていたのですが,どうもこの「CRTPによって静的多相性が実現できる」という言い方はおかしいのではないか,と思い直してきました.以下に例を示します.
#include <iostream> template<class T> class base{ public: void method(){ as_derived().method(); } protected: T &as_derived(){ return static_cast(*this); } T const &as_derived() const{ return static_cast<T const &>(*this); } }; class A : public base<A>{ public: void method(){ std::cout << "This is A::method()" << std::endl; } }; class B : public base<B>{ public: void method(){ std::cout << "This is B::method()" << std::endl; } }; template<class T> void some_process(base<T> &r) { r.method(); } int main(int argc, char *argv[]) { A a; some_process(a); B b; some_process(b); return 0; }
上のコードでは,確かにsome_processにおいてrが多相的に扱えています.が,rが多相的に扱えていることとCRTPによってbaseとA, Bに階層が組まれていることは本質的にまったく関係ないと思われるのです.some_processにおいてrが多相的に扱えると言いたいだけなら,以下のコードで良いはずなのです.
class A{ public: void method(){ std::cout << "This is A::method()" << std::endl; } }; class B{ public: void method(){ std::cout << "This is B::method()" << std::endl; } } template<class T> void some_process(T &r) { r.method(); }
some_processにおいてrが多相的に扱えるための最低限の要求は「"r.method()"というコードがコンパイルを通る(そしてsome_processが期待する意味を持つ)」であって,そこにCRTPが存在する理由は何一つないと思われるのです.
以上から,CRTPの効果という点でより厳密に述べるなら以下のほうが適切ではないか,と思うのですが・・・