Item41:了解隐式接口和编译期多态

纵使你从未使用过templates,应该不陌生“运行期多态”和“编译期多态”之间的差异。因为它类似于“哪一个重载函数该被调用(发生在编译期)”和“哪一个virtual函数应该被绑定(发生在运行期)”之间的差异。

加诸于template参数身上的隐式接口,就像加诸于class对象身上的显式接口一样真实,而且两者都在编译期完成检查,就像你无法以一种“与class提供之显式接口矛盾”的方式来使用对象(代码将不会通过编译)。你也无法在template中使用“不支持template所要求之隐式接口”的对象(代码一样不能通过编译)。


Item42:了解typename的双重意义

template<typename C>
void print2d(const C&container)//打印容器内的第二个元素
{
if(container.size()>=2){
C::const_iterator iter(container.begin());
++iter;
int value=*iter;
std::cout<<value;
}
}

iter的类型是C::const_iterator,实际是什么必须取决于template参数C,template内出现的名字如果相依与某个template参数,称之为从属名称,如果从属名称在class内呈现嵌套状,我们称之为嵌套从属名称,C::const_iterator就是这样一个名称,实际上它还是个嵌套从属类型名称。

嵌套从属名称有可能导致解析困难,在我们知道C是什么之前,没有任何办法可以知道C::const_iterator是否为一个类型,而当编译期开始解析template print2d时尚未确定C是神恶魔东西,C++有个规则可以解析这一状态。

如果解析器在template中遭遇一个嵌套从属名称,它便假设这个名称不是个类型,除非你告诉它是(用typename)。

一般性规则很简单:任何时候当你想要在template中指涉一个嵌套从属类型名称,就必须在使用它的前一个位置上放上关键字typename。

有一个例外:“typename必须作为嵌套从属类型名称的前缀词”,这一规则的例外是,typename不可能出现在base classes list内的嵌套从属类型名称之前,也不可能在member initialization list(成员初始化列表)中作为base class的修饰符。

总结:①申明template参数时,前缀关键字clas和typename可以互换。

②请使用关键字typename来标志嵌套从属类型名称:但不能在base class lists(基类列表)或member initialization list内以它作为base class的修饰符。


Item44:将参数无关的代码抽离templates

总结:①template生成多个classes和多个函数,所以任何template代码都不该与某个造成膨胀的template参数产生依赖关系。

②因非类型模版参数而造成的代码膨胀,往往可以消除,做法是以函数参数或class成员变量替换template参数。

③因类型参数而造成的代码膨胀,往往可以降低,做法是让带有完全相同二进制长度的具现类型共享实现代码。


Item45:运用成员函数模版接受所有兼容类型

总结:请使用member function template(成员函数模版)生成“可接受所有兼容类型”的函数。

如果你声明member template用于“泛化copy构造”或“泛化assignment操作”,你还是需要声明正常的copy构造函数和copy assignment操作符。


Item46:需要类型转换时要将模版定义为非成员函数

总结:当我们编写一个class template,而它所提供之“于此template相关的”函数支持“所有参数之隐式类型转换”时,请将那些函数定义为“class template 内部的friend函数”。


Item47:请使用traits classes表现类型信息

这一小结可以参考我的另一篇总结。

最新文章

  1. iOS 开发 -----公司测试打包上传流程
  2. C#操作mysql数据库
  3. Javascript跨域
  4. ThreadLocal工作原理
  5. AX2012R2使用SQL Server2014安装报表扩展报错
  6. SQL Server数据库表重置自增主键号(通常是指ID)
  7. mysql root强密码的必要性max_allowed_packet被改成1024引起的风险
  8. html5文章 -- HTML5开发实例-网易微博手机Web App开发过程
  9. 【转】Tomcat总体结构(Tomcat源代码阅读系列之二)
  10. DataTable或者DataRow转换对象
  11. 转:The Knuth-Morris-Pratt Algorithm in my own words
  12. 如何进去bios设置
  13. UWP APP 开发日记
  14. 上证A股股指跌破1900
  15. poi的合并单元格和冻结行列
  16. Schedule Problem spfa 差分约束
  17. JavaScript中函数引用调用和函数直接调用的区别
  18. flask Blueprint蓝图
  19. p4中如何rollback/backout merge/integration
  20. React Native之FlexBox布局

热门文章

  1. linux操作系统运行一个java程序并外网访问
  2. Linux实战笔记_CentOS7_无法识别NTFS格式的U盘
  3. 第一种方式:使用form表单将前端数据提交到servelt(将前端数据提交到servlet)
  4. 一天五道Java面试题----第九天(简述MySQL中索引类型对数据库的性能的影响--------->缓存雪崩、缓存穿透、缓存击穿)
  5. 齐博x1页面不直接报错,如何排查
  6. 从 Wepy 到 UniApp 变形记
  7. Python基础阶段总结:ATM项目实战
  8. 解决pip下载速度慢问题
  9. Excel常用需求
  10. 【k8s连载系列】2. k8s整体架构