参考:https://www.cnblogs.com/cynchanpin/p/7127897.html
模板类是一种泛型编程。
泛型编程:编写与类型无关的逻辑代码,是代码复用的一种手段。而模板是泛型编程的基础。
1、函数模板格式
template<typename Param1, typename Param2,...,class Paramn>
返回值类型 函数名(参数列表){
...
}
在C++的Template中有typename和class两个关键字,他们作用都是表明后面的符号为一个类型。在模板类的声明中,我们有两种方式
template <class T>
template <typename T>
在这里class和typename是相同的。在声明一个template type parameter(模板类型参数)时候,class和typename意味着完全相同的东西。
但是在C++中一些特性场合,必须要用typename。举一个例子:
template <class T>
class MyClass{
typename T::SubType * ptr;
......
};
此时,typename指出SubType是class T中定义的一个类别,因此ptr是一个指向T::SubType类别的指针。如果没有关键typename,SubType会被当成一个static成员,会被解释为T内的数值SubType与ptrl的乘积。
SubType成为一个型别的条件是,任何一个用来取代T的型别,其内部必须有一个内部型别(inner type)SubType的定义。
注意,如果要把一个template中的某个标识符号指定为一种型别,就算是意图显而易见,关键字typename也是不能省略的。因此C++的一般规则是,除了使用typename修饰之外,template内的任何标识符号都被视为一个值而不是一个型别。
2、类模板和模板类
类模板:一个类模板(类属类或类生成类)同意用户为类定义一种模式。使得类中的某些数据成员、默写成员函数的參数、某些成员函数的返回值,能够取随意类型(包含系统提前定义的和用户自己定义的)。
假设一个类中数据成员的数据类型不能确定。或者是某个成员函数的參数或返回值的类型不能确定。就必须将此类声明为模板,它的存在不是代表一个详细的、实际的类,而是代表着一类类。
类模板定义:
格式为:
template <class T>
class foo
{
...
}
foo为类名,在类定义体中个,如采用通用数据类型的成员,函数参数的前面需加上T。当中通用类型T能够作为普通成员变量的类型,还能够作为const和static成员变量以及成员函数的参数和返回类型之用。
template<class T>
class Test{
private:
T n;
const T i;
static T cnt;
public:
Test():i(0){}
Test(T k);
~Test(){}
void print();
T operator+(T x);
};
在类定义体外定义成员函数时,若此成员函数中有模板參数存在,则除了须要和一般类的体外定义成员函数一样的定义外,还需在函数体外进行模板声明 :
template<class T>
void Test<T>::print(){
std::cout<<"n="<<n<<std::endl;
std::cout<<"i="<<i<<std::endl;
std::cout<<"cnt="<<cnt<<std::endl;
}
在类定义体外初始化const成员和static成员变量的做法和普通类体外初始化const成员和static成员变量的做法基本上是一样的,唯一的差别是需再对模板进行声明
template<class T>
int Test<T>::cnt=0;
template<class T>
Test<T>::Test(T k):i(k){n=k;cnt++;}
类模板的使用 类模板的使用实际上是将类模板实例化成一个详细的类。它的格式为:类名<实际的类型>。
模板类是类模板实例化后的一个产物。
3、函数模板和模板函数
函数模板能够用来创建一个通用的函数。以支持多种不同的形参。避免重载函数的函数体反复设计。这也是类模板设计的初衷。
它的最大特点是把函数使用的数据类型作为参数。
声明形式:
template<typename(或class) T>
<返回类型><函数名>(參数表)
{
函数体
}
当中,template是定义模板函数的关键字;template后面的尖括号不能省略;typename(或class)是声明数据类型參数标识符的关键字。用以说明它后面的标识符是数据类型标识符。这样,在以后定义的这个函数中,凡希望依据实參数据类型来确定数据类型的变量,都能够用数据类型參数标识符来说明,从而使这个变量能够适应不同的数据类型。
template<typename(或class) T>
T fuc(T x, T y)
{
T x;
//……
}
函数模板仅仅是声明了一个函数的描写叙述即模板。不是一个能够直接运行的函数,仅仅有依据实际情况用实參的数据类型取代类型參数标识符之后,才干产生真正的函数。
模板函数:
模板函数的生成就是将函数模板的类型形參实例化的过程。
如下面例子:
double d;
int a;
fuc(d,a);
double fuc(double x,int y)
{
double x;
//……
}