仮想メンバー関数のオーバーヘッドを回避するために、C++でCRTPを使用するにはどうすればよいですか?
2つの方法があります。
1つ目は、型の構造に対してインターフェイスを静的に指定することです。
template <class Derived>
struct base {
void foo() {
static_cast<Derived *>(this)->foo();
};
};
struct my_type : base<my_type> {
void foo(); // required to compile.
};
struct your_type : base<your_type> {
void foo(); // required to compile.
};
2番目の方法は、ベースへの参照またはベースへのポインターイディオムの使用を回避し、コンパイル時に配線を行うことです。上記の定義を使用すると、次のようなテンプレート関数を使用できます。
template <class T> // T is deduced at compile-time
void bar(base<T> & obj) {
obj.foo(); // will do static dispatch
}
struct not_derived_from_base { }; // notice, not derived from base
// ...
my_type my_instance;
your_type your_instance;
not_derived_from_base invalid_instance;
bar(my_instance); // will call my_instance.foo()
bar(your_instance); // will call your_instance.foo()
bar(invalid_instance); // compile error, cannot deduce correct overload
したがって、関数で構造/インターフェース定義とコンパイル時の型推論を組み合わせると、動的ディスパッチではなく静的ディスパッチを実行できます。これが静的多型の本質です。
私は自分でCRTPのきちんとした議論を探していました。 Todd Veldhuizenの Scientific C++のテクニック は、この(1.3)および式テンプレートのような他の多くの高度なテクニックのための素晴らしいリソースです。
また、GoogleブックでCoplienのオリジナルのC++ Gemsの記事のほとんどを読むことができることがわかりました。たぶんそれはそうです。
調べる必要がありました [〜#〜] crtp [〜#〜] 。しかし、それを行った後、私は 静的多態性 についていくつかのものを見つけました。これがあなたの質問に対する答えだと思います。
[〜#〜] atl [〜#〜] はこのパターンを非常に広範囲に使用していることがわかりました。