【发布时间】:2013-08-22 01:33:31
【问题描述】:
我正在尝试减少模板函数实例化的数量,但遇到了障碍。
假设我们有以下类(我知道它没有优化:这样做是为了说明问题):
//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);
因此会减少代码大小。
但是唉!当我使用类层次结构时,代码大小会增加。这怎么可能?
如果我有以下代码,那就更奇怪了。
int main()
{
inherit<int, 4> v1;
inherit<int, 2> v2;
huge_func(v1);
huge_func(v2);
}
代码大小与调用huge_func(v1b)和huge_func(v2b)相同。
编译器在做什么?
【问题讨论】:
-
您是否真正查看过编译器生成的代码 - 换句话说,您是否确定第一个示例为您提供了两个不同的函数?
-
是的。在调试版本中,地图文件有两个不同的功能。不幸的是,启用 O3 后,地图文件不包含任何信息,因此那里有点神秘,但我只能假设这两个版本仍然以某种方式、形状或形式存在。
-
对,所以这可能是编译器在 O3 中内联代码的情况,所以你得到的代码更多,但代码相同。如果您想要更小的代码,请尝试使用 -Os。
-
-OS 存在相同的代码大小问题。事实上,我已经尝试了所有优化(O0、O1、O2、O3 和 OS),结果相同(层次结构生成更大的代码)。
标签: c++ templates optimization size