テンプレート関数のインスタンス化の数を減らそうとしていますが、問題が発生しています。
次のクラスがあるとします (最適化されていないことはわかっています。これは、問題を説明するために意図的に行われています)。
//class no_inherit is implemented the same way as class base (below).
//This is done to illustrate the issue I'm seeing.
template<typename T, size_t SIZE>
class no_inherit
{
private:
T m_data[SIZE];
const size_t m_size;
public:
no_inherit() :m_size(SIZE){}
T& operator[](size_t i)
{return m_data[i];}
inline size_t size() const
{return m_size;}
};
次の関数:
template<typename T>
void huge_func(T& v)
{
//..do lots of stuff with v. For example
for(size_t i = 0; i < v.size(); ++i)
v[i] = v[i] + i;
//...do lots more with v
}
そして、次のコード:
int main()
{
no_inherit<int, 4> v1;
no_inherit<int, 2> v2;
huge_func(v1);
huge_func(v2);
}
huge_func() は 2 回インスタンス化されます。
void huge_func(no_inherit<int, 4>& v);
void huge_func(no_inherit<int, 2>& v);
huge_func() は非常に大きいため、テンプレート パラメーターの 1 つを取得し、次のクラス階層を作成して動的パラメーターに変換することで、インスタンス化の数を削減しようとしています。
//Base class only has 1 template parameter.
template<typename T>
class base
{
private:
T *m_data;
const size_t m_size; //hold child's templated size parameter.
protected:
inline base(T* data, size_t size): m_data(data), m_size(size){}
public:
T& operator[](size_t i)
{return m_data[i];}
inline size_t size() const
{return m_size;}
};
//Child class has two template parameters
template<typename T, size_t SIZE>
class inherit: public base<T>
{
private:
T m_data[SIZE];
public:
//Pass template parameter to base class
inherit() : base<T>(m_data, SIZE){}
};
そして、次のように huge_func() を呼び出します。
int main()
{
inherit<int, 4> v1;
inherit<int, 2> v2;
//make sure only one instantiation of huge_func() is made
//by using the same type.
base<int> &v1b = v1;
base<int> &v2b = v2;
huge_func(v1b);
huge_func(v2b);
}
これは、単一の huge_func() 関数のみをインスタンス化します。
void huge_func(base<int>& v);
したがって、コードサイズが減少します。
しかし悲しいかな!クラス階層を使うとコードサイズが大きくなります。これはどのように可能ですか?
次のコードがある場合、さらに奇妙です。
int main()
{
inherit<int, 4> v1;
inherit<int, 2> v2;
huge_func(v1);
huge_func(v2);
}
コード サイズは、huge_func(v1b) と huge_func(v2b) を呼び出した場合と同じです。
コンパイラは何をしていますか?