我正在尝试减少模板函数实例化的数量,但遇到了障碍。
假设我们有以下类(我知道它没有被优化:这是为了说明问题而完成的):
//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()将实例化两次:
void huge_func(no_inherit<int, 4>& v);
void huge_func(no_inherit<int, 2>& v);
由于huge_func()非常庞大,我试图通过创建以下类层次结构中的一个模板参数并将其转换为动态参数来减少实例化计数:
//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);
因此会减少代码大小。
但ALAS!当我使用类层次结构时,代码大小会增加。这怎么可能?
如果我有以下代码,那就更加古怪了。
int main()
{
inherit<int, 4> v1;
inherit<int, 2> v2;
huge_func(v1);
huge_func(v2);
}
代码大小与调用huge_func(v1b)和huge_func(v2b)相同。
编译器在做什么?
答案 0 :(得分:0)
首先,如果huge_func
确实是“巨大的”,那么您可能会将其分成几个可重复使用的较小函数。
除此之外,您还可以模板化它:
template<typename T, int SIZE> void huge_func(no_inherit<T, SIZE>& v)
{
// function implementation goes here
}
然后你实现它一次,并保持你的平面类结构。