Boost.Arrayのような単純なクラスがあります。テンプレートパラメータTとNは2つあります。Boost.Arrayの欠点の1つは、そのような配列を使用するすべてのメソッドが、パラメータN(TはOK)のテンプレートでなければならないことです。その結果、プログラム全体がテンプレートになる傾向があります。1つのアイデアは、T(ArrayInterfaceのようなもの)のみに依存するインターフェイス(純粋仮想関数のみを含む抽象クラス)を作成することです。これで、他のすべてのクラスはインターフェイスにのみアクセスするため、テンプレートパラメーターTのみが必要になります(Nとは対照的に、多かれ少なかれ常に知られています)。ここでの欠点は、インターフェイスが使用されている場合、仮想呼び出しのオーバーヘッド(インライン呼び出しの機会を逃す機会が増える)です。ここまでは事実だけです。
template<typename T>
class ArrayInterface {
public:
virtual ~ArrayInterface() {};
virtual T Get(int i) = 0;
};
template<typename T, int N>
class Array : ArrayInterface<T> {
public:
T Get(int i) { ... }
};
template<typename T, int N>
class ArrayWithoutInterface {
public:
T Get() { ... }
};
しかし、私の本当の問題はどこかにあります。Boost.Arrayをインターフェイスで拡張すると、Boost.Arrayの直接インスタンス化が遅くなります(重要な場合は、ファクター4)。インターフェイスを削除すると、Boost.Arrayは以前と同じように高速になります。ArrayInterfaceを介してメソッドが呼び出された場合、オーバーヘッドが発生することは理解しています。しかし、純粋仮想メソッドのみを含む追加のインターフェイスのみがあり、クラスが直接呼び出される場合、メソッドの呼び出しが遅くなる理由がわかりません。
Array<int, 1000> a;
a.Get(0); // Slow
ArrayWithoutInterface<int, 1000> awi;
awi.Get(0); // Fast
GCC4.4.3とClang1.1は同じ動作を示します。