条款44:将与参数无关的代码剥离template

使用template时,不小心的时候可能就会带来代码膨胀的问题:

1 template<typename T,
2             std::size_t n>
3 class SquareMatrix{
4 public:
5     void invert();
6 };
7 //而对于下面两份模版实例化
8 SquareMatrix<double, 10> ma10;
9 SquareMatrix<double, 5 > ma5;

这两个实例化除了特殊的数字之外,其他的所有参数代码都是一样的,这就带来了所谓的代码膨胀,而避免上面这种状况的一个有效办法就是,让这个带有typename的template作为基类:

1 template<typename T>
2 class SquareMatrixBase{
3 protected:
4     void invert(std::size_t matrixSize);//这里的size_t相当于减少了代码实例化的机会
5 };
1 template<typename T,
2 std::size_t n>
3 class SquareMatrix : private SquareMatrixBase<T>{
4 private:
5     using SquareMatrixBase<T>::invert;
6 public:
7     ...
8     void invert(){this->invert(n);}//这里制造了inline调用,降低调用的开销,使用this是为了访问这个成员被模板的影响所遮盖
9 }
但是这里还有个问题,就是derived class中使用的数据T 是存在与base class中的。
一种方法是给基类的数据一个private指针:
 1 template<typename T>
 2 class SquareMatrixBase{
 3 protected:
 4     SquareMatrixBase(std::size_t n, T *pMem):
 5     size(n), pData(pMem){}
 6     void setDataPtr(T * ptr){pData =ptr;}
 7     ...
 8 private:
 9     T data[n*n];
10 };
还有一种就是动态分配内存,不过大体的过程是一样的。
使用这些方法,就使得不同大小的矩阵只是拥有者单一版本的invert。
这个问题讨论的主要是非类型模板参数带来的代码膨胀
小结:
    Template生成多个函数以及多个class,所以template的代码都不应该与某个造成依赖的参数产生关系
    上面讨论的是非类型模板参数带来的膨胀,往往可以正常消除
    
posted @ 2015-10-18 17:05  eversliver  阅读(386)  评论(0编辑  收藏  举报