More C++ Idioms/薄いテンプレート(Thin Template)
薄いテンプレート(Thin Template)
[編集]意図
[編集]多数の型に対してクラステンプレートがインスタンス化された時の、オブジェクトコードの重複を削減する。
別名
[編集]動機
[編集]テンプレートはソースコードを再利用する方法の一つであり、オブジェクトコードの再利用はしない。 テンプレートはクラスの一族全体を定義することができる。 その一族のインスタンス化された各要素(クラス)は、それぞれのオブジェクトコードを必要とする。 クラステンプレートや関数テンプレートがインスタンス化される場合はいつでも、 その型独自のオブジェクトコードが生成される。 パラメータ化された型の数が増えると、オブジェクトコードも増える。 よく最適化されたコンパイラは、プログラム中で使用されているクラステンプレートの関数に対するオブジェクトコードだけを生成する。 それでも、オブジェクトコードの重複はメモリがそれほど潤沢ではない環境では問題となりうる。 同じオブジェクトコードの再利用は、命令キャッシュの効率と従ってアプリケーションの性能も改善しうる。 従って、オブジェクトコードの重複を削減することが望ましい。
解法とサンプルコード
[編集]薄いテンプレートイディオムは、オブジェクトコードの重複を削減するために使用される。 オブジェクトコードレベルで再利用可能なコードは、一般的には基本クラスで一度だけ書かれ、 別に配置可能な .dll や .so ファイルにコンパイルされる。 基本クラスは型安全ではないが、型安全な「薄いテンプレート」ラッパが、ほとんど(あるいは全く)オブジェクトコードの重複なしに、失われた型安全性を提供する。
// 非テンプレート
class VectorBase {
void insert (void *);
void *at (int index);
};
template <class T>
class Vector<T*> // 薄いテンプレート
: VectorBase
{
inline void insert (T *t) {
VectorBase::insert (t);
}
inline T *at (int index) {
return VectorBase::at (index);
}
};
基本クラスは非常に大きいかもしれないし、任意の量のコードを含むかもしれない。 このクラスはインライン関数のみを使用しているので、追加のコードは生成されない。 しかし、キャストがインライン関数のなかにカプセル化されているため、このクラスは使用者にとっては型安全である。 テンプレート化されたクラスは薄い。
既知の利用
[編集]Symbian OS はこのイディオムを多数使用している。例えば
template <class T> class CArrayFix : public CArrayFixBase
で、CArrayFixBase が全ての作業を行う。