zoukankan      html  css  js  c++  java
  • 条款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的代码都不应该与某个造成依赖的参数产生关系
        上面讨论的是非类型模板参数带来的膨胀,往往可以正常消除
        
  • 相关阅读:
    python自动发邮件库yagmail
    Vmware改成bridge方式联网
    centos7 更新Firefox版本
    无法应用转换程序,请检查指定的转换程序路径是否有效
    python中list/tuple/dict/set的区别
    Python中的*arg和**kwarg
    centos7.4下搭建JDK+Tomcat+Nginx+Mysql+redis+Mongodb+maven+Git+Jenkins
    用 Apache Derby 进行 ODBC 编程
    Derby 命令
    Python与数据库
  • 原文地址:https://www.cnblogs.com/-wang-cheng/p/4889815.html
Copyright © 2011-2022 走看看