Templates
及泛型编程的世界,与面向对象有根本上的不同。在此世界中显示接口和运行期多态仍然存在,但重要性低;隐式接口和编译器多态更为重要。
41 Understand implicit interfaces and compile-time polymorphism
- 加诸于
template
参数身上的隐式接口,就像加诸于class
对象身上的显式接口一样真实,而且两者都在编译器完成检查; classes
和templates
都支持接口和多态;- 对
classes
而言是显式的,以函数签名为中心。多态则是通过virtual
函数发生于运行期; - 对
template
参数而言,接口是阴式的,奠基于有效表达式。多态则是通过template
具现化和函数重载解析发生于编译期;
42 Understand the two meanings of typename
- 任何时候当你想要在
template
中指涉一个嵌套从属类型名称,就必须在紧邻它的前一个位置放上关键字typename
;typename
不可以出现在base classes list
内的嵌套从属类型名称前,也不可在成员初始列中作为base class
修饰符; typename
只被用来验明嵌套从属类型名称,其他名称不该有它存在;- 声明
template
参数时,前缀关键字class
与typename
可以互换;
43 Know how to access names in templatized base classes
- 可在
derived class template
内通过“this->
”指涉base class templates
内的成员名称,或藉由一个明白写出的“base class
资格修饰符”完成;
44 Factor parameter-independent code out of templates
Template
生成多个classes
与多个函数,所以任何template
代码都不该与某个造成膨胀的template
参数产生相依关系;- 因非类型模板参数而造成的代码膨胀,往往可消除,做法是以函数参数或者
class
成员变量替换template
参数; - 因类型参数而造成的代码膨胀,往往可降低,做法是让带有完全相同二进制表述的具现类型共享实现码;
45 Use member function templates to accept “all compatible types”
- 请使用
member function templates
(成员函数模板)生成“可接受所有兼容类型”的函数; - 如果你声明
member templates
用于“泛化copy
构造”或“泛化assignment
操作”,你还是需要声明正常的copy
构造函数和copy assignment
操作符;
46 Define non-member functions inside templates when type conversions are desired
- 当我们编写一个
class template
,而它所提供之“与此template
相关的”函数支持“所有参数之隐式类型转换”时,请将那些函数定义为“class template
内部的friend
函数”;
47 Use traits classes for information about types
Traits class
使得类型相关信息可以在编译期可用,它们以template
和template
特化完成实现;- 整合重载技术后,
traits classes
有可能在编译期对类型执行if-else
测试;
48 Be aware of template metaprogramming
Template metaprogramming
(TMP
,模板元编程)可将工作由运行期转移到编译期,因而得以实现早期错误侦测或者更高的执行效率;TMP
可被用来生成“基于政策选择组合”(based on combinations of policy choices
)的客户定制代码,也可以用来避免生成对某些特殊类型并不适合的代码;