技术是实现目标的手段和方式,模板的存在,是为了让程序猿能编写出与类型无关的代码,而编写与类型无关的代码,则是为了代码的复用,让程序更美观,更容易维护,所有这些,都是为了提高生产效率。

        函数模板的格式

template <class 形参1,  class  形参2, .....>  返回类型  函数名(参数列表)
{
函数体
}


       不论何时,都不要忘记template   ,没有它,就不是模板了


typename 来修饰


    接下来是返回类型,和函数名,这个没什么好说的,非模板的函数也得有这两个东东


    小括号内(),放的是函数的参数,这里既可以放前面中括号里的形参,也可以放其他类型的参数,比如int long


    下面,给出一个函数模板的例子


     

//  如果t1比t2大,就返回true,反之,返回false
template<class T> bool IsBigger(const T& t1,const T&t2)
{
return t1>t2?true:false;
}
int main()
{
int i = 8;
int j = 6;
if(IsBigger(i,j))
{
cout<<"大于"<<endl;
}
return 1;
}



      我们前面已经讲过,使用模板技术,是为了编写与类型无关的程序,那么,是否意味着我们传入任意类型的数据都可以呢?看下面这段代码


      

//  如果t1比t2大,就返回true,反之,返回false
template<class T> bool IsBigger(const T& t1,const T&t2)
{
return t1>t2?true:false;
}

class Data
{
public:
int iData;
Data(int i)
{
iData = i;
}
};


int main()
{
Data d1(5);
Data d2(3);
if(IsBigger(d1,d2))
{
cout<<"大于"<<endl;
}
return 1;
}



      和第一段代码不同的是,这一次,我们传入的不再是基础数据类型,而是一个对象,然而在编译时,却生成一大堆错误,虽然现在的编译器已经非常智能,但仍然没有办法明确的告知你问题出在哪里。


      问题出在

return t1>t2?true:false;


      如果传入的是基础类型的数据,那么没有任何问题,但如果传入的是对象,对象就必须重载>运算符,否则,模板是不知道该如何比较他们两个之间的大小的,因此修改Data即可


      

class Data
{
public:
int iData;
Data(int i)
{
iData = i;
}

// 注意,一定要在小括号的后面加const
bool operator >(const Data& d)const
{
return iData>d.iData?true:false;
}
};


       注意看我们的模板,传入的两个参数都是引用,且用const来修饰,这就表示,这个模板函数不能修改他们的值,而模板函数内在进行大小比较时又会调用Data重载的>函数,那么,这就要求重载>的函数内,也不能对Data对象的内容进行修改,因此要加上const



       一个类的函数的小括号后面如果加了const,就表示,这个函数体内不能对该类对象的成员变量做任何修改