目录
一、为什么要定义模板
现在的 C++ 编译器实现了一项新的特性:模板( Template ),简单地说, 模板 是一种通用的描述机制,也就是说,使用模板允许使用 通用类型 来定义函数或类等,在使用时,通用类型可被具体的类型,如 int 、 double 甚至是用户自定义的类型来代替。模板引入一种全新的编程思维方式,称为 “ 泛型编程 ” 或 “ 通用编程 ” 。泛型编程:不是针对某一种具体的类型进行编程,而是针对一类类型进行编程,将类型抽象成T(类型参数化)
#形象地说,把函数比喻为一个游戏过程,函数的流程就相当于 游戏规则。#在以往的函数定义中,总是指明参数是 int 型还是 double 型等等,这就像是为张三(好比 int 型)和李四(好比 double 型)比赛制定规则。可如果王五( char* 型)和赵六( bool 型)要比赛,还得提供一套函数的定义,这相当于又制定了一次规则,显然这是很麻烦的。#模板的的引入解决了这一问题 ,不管是谁和谁比赛,都把他们定义成 A 与 B 比赛,制定好了 A 与 B 比赛的规则(定义了关于 A 和 B 的函数)后,比赛时只要把 A 替换成张三,把 B 替换成李四就可以了, 大大简化了程序代码量 , 维持了结构的清晰 , 大大提高了 程序设计 的效率 。该过程称为 “ 类型参数化 ” 。# 强类型程序设计中,参与运算的所有对象的类型在编译时即确定下来,并且编译程序将进行严格的类型检查。为了解决 强类型的严格性和灵活性的冲突。有以下3中方式解决:#带参数宏定义 (原样替换)#重载函数 (函数名相同,函数参数不同)#模板 (将数据类型作为参数)#include <iostream> using namespace std; int add(int x, int y) //定义两个int类型相加的函数 { return x + y; } double add(double x, double y) //重载两个double类型相加的函数 { return x + y; } char* add(char* px, char* py) //重载两个字符数组相加的函数 { return strcat(px, py); //调用库函数strcat } int main() { cout << add(1, 2) << endl; //调用add(const int,const int) cout << add(3.0, 4.0) << endl; //调用add(const double,const double) char x[10] = "Hello "; //创建字符数组,注意要留够大小 char y[] = "C++"; cout << add(x, y) << endl; //调用add(char*,char*) return 0; }
模板的优点:
1、简化程序,少写代码,维持结构的清晰,大大提高程序的效率。
2、解决强类型语言的严格性和灵活性之间的冲突。
2.1、带参数的宏定义(原样替换)
2.2、函数重载(函数名字相同,参数不同)
2.3、模板(将数据类型作为参数)
3、强类型语言程序设计:C/C++/Java等,有严格的类型检查,如int a = 10,在编译时候明确变量的类型,如果有 问题就可以在编译时发现错误,安全,但是不够灵活,C++引进auto其实就是借鉴弱类型语言的特征。
弱类型程序语言设计:js/python等,虽然也有类型,但是在使用的时候直接使用let/var number,不知道变量具体类型,由编译器解释变量类型,属于解释型语言。如果有错,到运行时才发现,虽然灵活,但是不安全。
二、模板的定义
#模板的引入使得函数定义摆脱了类型的束缚,代码更为高效灵活。 C ++中,通过下述形式定义一个模板:template <class T,...>
或
template<typename T,....>
#早期模板定义使用的是 class ,关键字 typename 是最近才加入到标准中的,相比 class , typename 更容易体现 “ 类型 ” 的观点,虽然两个关键字在模板定义时是等价的,但从代码兼容的角度讲,使用 class 较好一些。#模板有 函数模板 和 类模板 之分。通过 参数实例化 构造出具体的函数或类,称为 模板函数 或 模板类