Effective C++第七章-模板和泛型编程之模板特化和代码膨胀

来源:互联网 发布:javascript引用ku 编辑:程序博客网 时间:2024/06/05 10:01

模板特化

class A{public:    void func1();    void func2();};class B{  public:    void func1();    void func2();};template<typename company>class manager{public:    void dofun1()    {        company c;        c.fun1();    }    void dofun2()    {...}};template<typename company>class bettermanager : public manager<company>{public:    void dobetterfun1()    {         dofun1();//调用模板化基类:manager<company>的函数,无法通过编译    }};

问题在于,当编译器遇到bettermanager类的定义式时,由于不知道模板化基类manager< company >中的模板参数company 的值,因此不知道继承的是什么样的class,就无法知道manager< company >是否有dofun1函数。

比如说:

class C{public:    void func2();};//一个针对类型C特化的manager,而且特化是全面性的,也就是说一旦类型参数被定义为C,再没有其他模板参数可供变化template<>class manager<C>{public:    void dofun2(){...}};

此时的bettermanager代码中,如果class bettermanager : public manager< company >的company是C,manager< C >模板化基类没有dofun1函数。

因此C++拒绝这个调用的原因:它知道base class template(manager< company >)有可能被特化(C),而那个特化版可能不提供和一般性template相同的接口。

模板参数造成的代码膨胀(代码膨胀=相同部分的重复)

两个函数或类中的某些部分的实现码实质相同时,可以抽出两个函数或类中共同部分,放进新的函数或类,然后令两个函数调用新函数或使用继承或复合取用新类。但是在模板代码中,重复是隐晦的:毕竟只存在一份模板源码,所以必须训练自己去感受当模板被具体实现化多次时可能发生的重复。

template<typename T,std::size_t n>//n为非类型模板参数,T为类型模板参数class A{...};

Template生成多个classes与多个函数,所以任何template代码都不该与某个造成膨胀的template参数产生相依关系。

  1. 因非类型模板参数而造成的代码膨胀,往往可以消除,做法是以函数参数或者class成员变量替换template参数。
  2. 因类型参数而造成的代码膨胀,也可以降低,做法是让带有完全相同二进制表述的具现类型共享实现码。
原创粉丝点击