C++
Curiously recurring template pattern
#include <iostream>
using namespace std;
template<typename T>
class base{
public:
void func1(){
static_cast<T*>(this)->implementation();
}
void func2(){
cout << "base" << endl;
}
};
class delived1 : public base<delived1>{
public:
void implementation(){
cout << "delived1" << endl;
}
};
void main(){
delived1 d1;
d1.func1();
}
こんな立派なパターン名があるとは知らなかったが、要は vtbl を使わずにポリモーフィックを実現するというものだ。
static_cast<T*>(this)
が肝。
ところで、面白いのが次のようにやってもコンパイルできる事。
class delived2 : public base<delived2>{
};
void main(){
delived2 d2;
d2.func2();
}
delived2 は implementation() を実装していない(実装していないどころか存在がない)ので、base のテンプレートパラメータとしては不合格なはずだが、コンパイルもできるし実行もできる。これは、func1() を呼び出していないおかげで、delived2 に implementation() があろうがなかろうが関係なくなっているため、C++ コンパイラはこれを実体化しないからである。
次のように書いた途端、コンパイルできなくなる。
void main(){
delived2 d2;
d2.func1();
}