基本使用
声明前:加template < class / typename T>
告诉编译器紧跟的代码里出现T不要报错
声明:mySwap( T &a T &b )
类型也需要传入 ,类型参数化
调用:
自动类型推导:myswap(a,b)
自动类型推导 按照a、b的类型来替换T
显示指定类型:myswap<int>(a,b)
函数模板
与普通函数区别:普通函数可以进行隐式类型转换,模板不可以
调用规则:
c++编译器有限考虑普通函数,func<>(参数)
强制调用模板,<>是空模板参数列表
函数模板可以像普通函数那样呗重载
如果函数模板可以产生更好的匹配,那么选择模板 (如普通函数要类型转换时)
模板机制:
模板不能直接调用,生成后的模板函数才可以调用
二次编译,第一次对模板进行编译,第二次对替换T类型后的代码进行二次编译
模板局限性
模板不能操作所有的类型,不同类型的操作不同。
解决:已有模板时,具体化来解决问题template<> 返回值 函数名<具体类型>(参数)
,告知编译器遇到这种类型时用这个函数
类模板
●写法:template <class T>
后面声明类
●与函数模板区别:
类模板可以有默认类型参数
函数模板可以进行自动类型推导,类模板不可以,必须指定类型
●注意:类模板中的成员函数一开始不会创建,运行时才去创建
●成员函数类外实现
template <class T1, class T2>
Person<T1, T2>::Person(T1 name, T2 age)
●类模板做函数的参数的三种方式:
1.显示指定类型
2.参数模板化:
3.整体模板化:
类模板与继承
注意:基类如果是模板类,必须让子类告诉编译器 基类中的T到底是什么类型。如果不告诉,那么无法分配内存,编译不过
使用:利用参数列表class Child :public Base<int>
类模板的分文件编写
问题:类模板的成员函数运行阶段才创建,导致包含.h头文件不会创建函数的实现,无法解析外部命令
解决:不要分文件编写,写到同一个文件中,进行声明和实现,后缀名改为.hpp(hpp一般用来写模板)
类模板碰到友元函数
●类内实现
friend void printPerson( Person<T1 ,T2> & p ) {}
●类外实现
1.类内声明:
friend void printPerson<>(Person<T1, T2> & p); //多了个<>,和普通函数声明区分
2.让编译器看到 函数 并且看到这个Person类型(函数要用到)
3.实现:
void printPerson(Person<T1, T2> & p){}