面向对象编程(OOP)和泛型编程都能处理在编写程序时不知道类型的情况。不同之处在于:OOP能处理类型在程序运行之前都未知的情况;而在泛型编程中,在编译时就能获知类型了。

前面介绍的容器、迭代器和算法都是泛型编程的例子。当我们编写一个泛型程序时,是独立与任何特定类型来编写代码的。当使用一个泛型程序时,我们提供类型或值,程序实例可在其上运行。

模板是泛型编程的基础。一个模板就是一个创建类或函数的蓝图或者说公式。当使用一个vector这样的泛型类型,或者find这样的泛型函数时,我们提供足够的信息,将蓝图转换为特定的类型函数。这种转换发生在编译时。

定义模板

假定我们希望编写一个函数来比较两个值,并指出第一个值是小于、等于还是大于第二个值。在实际中,我们可能想要定义多个函数,每个函数比较一个给定类型的值。我们的初次尝试可能定义多个重载函数:

int compare(const string &v1,const string &v2)

{if(v1v2) return 1;return 0;

}int compare(const double &v1,const string &v2)

{if(v1v2) return 1;return 0;

}

这两个函数几乎相同,唯一的差别是参数的类型,函数体则完全一样。

如果对每种希望比较的类型都不得不重复定义完全一样的函数体,是非常烦琐且容易出错的。更麻烦的是,在编写程序的时候,我们就要确定可能要compare的所有类型。

函数模板

我们可以定义一个通用的函数模板,而不是为每个类型都定义一个新函数。一个函数模板就是一个公式,可用来生成针对特定类型的函数版本。compare的模板版本可能像下面这样:

template

int compare(const T&v1,const T &v2)

{if(v1v2) return 1;return 0;

}

模板定义以关键字template开始,后跟一个模板参数列表,这是一个逗号分隔的一个或多个模板参数的类表,用小于号()包围起来。

在模板定义中,模板参数列表不能为空。

模板参数列表的作用很像函数参数列表。函数参数列表定义了若干特定类型的局部变量,但并未指出如何初始化它们。在运行时,调用者提供实参来初始化形参。

类似的,模板参数表示在类或函数定义中用到的类型或值。当使用模板时,我们(隐式地或显式地)指定模板实参(template argument),将其绑定到模板参数上。

我们的compare函数声明了一个名为T的类型参数。在compare中,我们用名字T表示一个类型。而T 表示的实际类型则在编译时根据compare的使用情况来确定。

实例化函数模板

当我们调用一个函数模板时,编译器(通常)用函数实参来为我们推断模板实参。即,当我们调用compare时,编译器使用实参的类型来确定绑定到模板参数T的类型。例如,在下面的调用中:

cout<

实参类型是int。编译器会推断出模板实参为int,并将它绑定到模板参数T。

编译器用推断出的模板参数来为我们实例化一个特定版本的函数。当编译器实例化一个模板时,它使用实际的模板实参代替对应的模板参数来创建出模板的一个新“实例”。

例如,给定下面的调用:

//实例化出int compare(const int&,const int&)

cout<

//实例化出 int compare(const vector&,const vector&)

vector vec1(1,2,3),vec2(4,5,6);

cout<

编译器会实例化出两个不同版本的compare。对于第一个调用,编译器会编写并编译一个compare版本,其中T被替换为int:

int compare(const int &v1,const int &v2)

{if(v1v2) return 1;return 0;

}

对于第二个调用,编译器会生成另一个compare版本,其中T被替换为vector,这些编译器生成的版本通常被称为模板的实例。

模板类型参数

我们的compare函数有一个模板类型参数,一般来说,我们可以将类型参数看作类型说明符,就像内置类型或类类型说明符一样使用。特别是,类型参数可以用来指定返回类型或函数的参数类型,以及在函数体内用于变量声明或类型转换。

类型参数必须使用关键字class或typename:

//错误:U之前必须加上class或typename

template T calc(const T&,const U&);

在模板参数列表中,这两个关键字的含义相同,可以相互转换使用。一个模板参数列表中可以同时使用这两个关键字:

//正确:在模板参数列表中,typename和class没有什么不同

template calc(const T&,const U&);

看起来用关键字typename来指定模板类型参数比用class更为直观。毕竟,我们可以用内置(非类)类型作为模板类型实参。而且,typename更清楚地指出随后的名字是一个类型名。

非类型模板参数

除了定义类型参数,还可以在模板定义中定义非类型参数。一个非类型参数表示一个值而非一个类型。我们通过一个特定的类型名而非关键字class 或 typename来指定非类型参数。

当一个模板被实例化时,非类型参数被一个用户提供的或编译器推断出的值所代替。这些值必须是常量表达式,从而允许编译器在编译时实例化模板。

java定义类模板_定义模板——函数模板和类模板相关推荐

  1. 苹果cms10好看的模板_简洁黑色自适应苹果CMSv10网站模板

    苹果cms10好看的模板_简洁黑色自适应苹果CMSv10影视模板 我的主题网[第十四套]苹果CMSv10最新原创酷黑渐变特色自适应视频站模板 酷黑渐变特色功能触动封面直接播放视频内容,苹果cms自适应 ...

  2. 深入篇【C++】类与对象:友元函数与友元类

    深入篇[C++]类与对象:友元函数与友元类 ①.提出问题:重载operator<< ②.解决问题:友元 Ⅰ.友元函数 [特点] Ⅱ.友元类 [特点] ③.总结问题 ①.提出问题:重载ope ...

  3. C++ 泛型编程(一):模板基础:函数模板、类模板、模板推演成函数的机制、模板实例化、模板匹配规则

    文章目录 泛型编程 函数模板 函数模板实例化 隐式实例化 显式实例化 函数模板的匹配规则 类模板 类模板的实例化 泛型编程 泛型编程旨在削减重复工作,如: 将一个函数多次重载不如将他写成泛型. voi ...

  4. velocity模板_使用Velocity进行客户端和服务器端模板

    以标准表示或交换格式(例如HTML和XML)操作和转换文本数据是每个软件开发人员都参与的频繁且通常乏味的活动. 模板引擎可以通过在模板中维护输出的静态部分,同时动态生成和定位变化部分来促进此过程. V ...

  5. h5 bootstrap 小程序模板_汉中餐饮行业支付宝小程序模板

    汉中餐饮行业支付宝小程序模板 r2y8w85 汉中餐饮行业支付宝小程序模板 在上,都能够开设自身的美妆旗舰店,根据这类方法开展精细化的服务,随后去一些线下用户流量.命名合适的小程序名称商城在搭建过程之 ...

  6. onclick=两个函数_[译]React函数组件和类组件的差异

    [译]React函数组件和类组件的差异 原文: https://overreacted.io/how-are-function-components-different-from-classes/ 在 ...

  7. 应付账款账龄分析模板_超全的财务会计表单模板分享

    还在为了工作而心乱如麻? 还在网上茫无头绪的找模板? 还在对找的而模板无所适从? 相信不少新入门的会计 甚至一些做了不少时间的老会计 也时常会为一些财务表格而发愁 如果还有朋友还在为了这事而心乱如麻 ...

  8. 微软crm在哪新建审批模板_如何在Microsoft Word中创建模板

    微软crm在哪新建审批模板 Templates let you configure all the relevant settings you want pre-applied to document ...

  9. wordpress模板_如何在WordPress中创建类别模板

    wordpress模板 Have you visited a site where each category has different layout? In WordPress theme dev ...

  10. 单例模式访问mysql设计类图_利用单例模式设计数据库连接Model类

    之前在<[php]利用php的构造函数与析构函数编写Mysql数据库查询类>(点击打开链接)写过的Mysql数据库查询类还不够完美,利用<[Java]单例模式>(点击打开链接) ...

最新文章

  1. python3.7.2教程-centos7系统下python2与python3共存
  2. libevent中的bufferevent
  3. Laravel 5.0 的新特性
  4. img图片下多余空白的BUG解决方案
  5. FFmpeg 4.0版发布
  6. c++中多线程传递参数原理分析
  7. 体验最火的敏捷——SCRUM(厦门,2014.1.4)
  8. Linux中实现远程登录Xshell和Xftp
  9. 某个知名技术论坛用户名和密码泄露(第一部分)
  10. 一个入门级的Java Applet
  11. openfire User Service 和删除分组的方法
  12. RC正弦波振荡电路Ltspice仿真
  13. dnf喇叭怎么设置不显示服务器,《DNF》屏蔽广告喇叭方法 广告喇叭怎么关掉
  14. Android call requires API level 12 的解决方案
  15. 抖音专业运营方案及策略技巧
  16. 2017年12月。。
  17. 【文献学习】Analysis of Deep Complex-Valued Convolutional Neural Networks for MRI Reconstruction
  18. pygame-KidsCanCode系列jumpy-part16-enemy敌人
  19. 【软件测试】自动化测试战零基础教程——Python自动化从入门到实战(一)
  20. Python制作翻译工具(程序员必备中英文翻译工具)

热门文章

  1. 集合之扑克牌---洗牌+发牌+发牌后排序+看牌
  2. antd vue form 手动校验_Ant Design 4.0 的一些杂事儿 - Form 篇
  3. MYSQL登录遇到的问题:解决ERROR 2003 (HY000): Can‘t connect to MySQL server on ‘localhost:3306‘(10061)
  4. 杂类--------文字型码表(备份)
  5. c语言函数大全 pdf,C语言标准库函数大全.pdf
  6. 爬虫 | 王者荣耀高清壁纸-单线程
  7. 【PC】电子书阅读软件推荐
  8. 用 matplotlib 绘制 3D 时间序列动态图
  9. 浏览器翻译功能在哪里,如何使用浏览器翻译网页
  10. 北京市基本医疗保险A类定点医疗机构名单(2010-09-29)