Item41:了解隐式接口和编译期多态
Understanding implicit interfaces and compile-time polymorphism.
编译期多态: 模板根据类型实例化;重载函数。
运行期多态: 运行时决定那个一个virtual函数被调用。
Item42:了解typename的双重意义
Understand the two meanings of typename.
- 声明template参数时,class和typename意义相同
- typename用于标识嵌套从属类型名称:但不得在类派生列表,成员初始化列表使用。
Item43:学习处理模版化基类内的名称
Know how to access names in templatized base classes.
在派生类模板中调用基类模板中的函数时,无法直接调用,因为可能特例化基类中无此函数,所以C++不会在模板化基类中去寻找。
解决: 当我们确保所有特例化版本都支持该接口时
①this->访问基类模板成员
②using Base::func指示编译器去Base中查找
③Base::func显示访问,但此时无多态性
Item44:将与参数无关的代码抽离templates
Factor parameter-independent code out of templates.
因非类型模板参数造成的代码膨胀,可通过以函数参数或class成员变量替换template参数。书中将重复定义的invert函数抽取到SquareMatrixBase中。
Item45:运用成员函数模版接受所有兼容类型
Use member function templates to accept "all compatible"types.
smartPtr< Derived >与smartPtr< Base >完全是两个类型,不存在转换关系,为实现smartPtr< Derived >➡️smartPtr< Base >转换
①使用成员函数模板生成“可接受所有兼容类型的函数”。
②声明member templates用于“泛化copy构造”或“泛化assignment操作”,并不会阻止编译器生成它们自己的copy构造函数。
template<typename T>
class shared_ptr{
public:
template<typename U>
shared_ptr(const shared_ptr<U>&p):mem_p(p.get()){...}
private:
T *mem_p;
};
Item46:需要类型转换时请为模版定义非成员函数
Define non-member funtions inside templates when type conversions are desired.
- 为了模板化实现Item24中Rational类的operator *
- 需要将声明与实现都放到class中,但此时便会inline,所以对于大型复杂的函数,可将应用部分放在类外进行内部调用
Item47:请使用traits classes表现类型信息
Use traits classes for information about types.
- Traits classes 使得“类型相关信息”在编译期可用,它们以template(类型本身带有信息)以及templates特例化(内置类型)实现。
- 整合重载技术后,traits classes可在编译期对类型执行if…else测试,来确定相应的函数调用。使之提高运行期执行效率。
Item48:认识template元编程
Be aware of template metaprogramming.
Template metaprogramming(TMP)可将工作由运行期移往编译期,因而得以实现早期错误侦测和更高的执行效率。