0

我正在尝试减少模板函数实例化的数量,但遇到了障碍。

假设我们有以下类(我知道它没有优化:这样做是为了说明问题):

//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) 相同。

编译器在做什么?

4

1 回答 1

0

首先,如果huge_func确实“巨大”,您可能会受益于将其拆分为几个可重用的较小函数。

除此之外,您还可以对其进行模板化:

template<typename T, int SIZE> void huge_func(no_inherit<T, SIZE>& v)
{
    // function implementation goes here
}

然后你实现它一次,并维护你的扁平类结构。

于 2013-08-21T17:33:31.997 回答