1.什么是模板
假设现在我们完成这样的函数,给定两个数x和y求式子x^2 + y^2 + x * y的值 .考虑到x和y可能是 int , float 或者double类型,那么我们就要完成三个函数:
int fun(int x,int y);
float fun(float x,float y);
double fun(double x,double y);
并且每个fun函数内部所要完成的操作也是极其的相似。如下:
2.模板函数
实际上我们利用函数模板,只需要一个函数就可能完成上面的三个函数了,千言万语不如看代码:
using namespace std;
template <typename T>
T fun(T x,T y)
{
T tmp = x *x + y * y + x * y;
return tmp;
}
int main()
{
int x1 = 1,y1 = 4;
float x2 = 1.1 , y2 = 2.2;
double x3 = 2.0 , y3 = 3.1;
cout<<fun(x1,y1)<<endl;
cout<<fun(x2,y2)<<endl;
cout<<fun(x3,y3)<<endl;
return 0;
}
</div>
运行结果:
如此利用模板,我们很轻而易举的达到了我们的目的,而这也大大的提高了代码的可重用性,这也让我们想起了STL中的那些算法了吧,这些算法使用多种的数据类型。实际上STL即使模板的重要应用了。
现在我们想,如果上面的代码这样调用fun(x1,y2)会怎么样呢?点击编译会出现这样的错误:
可以看到编译编译出现问题的是fun(x1,y2),说的意思就是没有对应的函数,要么x1和y2都是int型,要么x1和y2都是float型。那么我为什么要说一下这样一种情况呢?主要是为了引出模板也可以同时使用两个:
using namespace std;
template <typename T1 , typename T2>
T2 fun(T1 x,T2 y)
{
T2 tmp = x *x + y * y + x * y;
return tmp;
}
int main()
{
int x1 = 1,y1 = 4;
float x2 = 1.1 , y2 = 2.2;
double x3 = 2.0 , y3 = 3.1;
cout<<fun(x1,y1)<<endl;
cout<<fun(x2,y2)<<endl;
cout<<fun(x3,y3)<<endl;
cout<<fun(x1,y2)<<endl;
return 0;
}
</div>
运行结果:
当使用两个模板时,为什么fun(x1,y1)也能正确运行呢?因为当进行这个调用时,T1 = int ,T2 = int。所以这种调用也是没有问题的。
提到函数想到重载是很自然的吧,那么模板函数能不能重载呢?显然是能的了,还是看代码:
using namespace std;
template <typename T1 , typename T2>
T2 fun(T1 x,T2 y)
{
cout<<"调用了两个个参数的 fun 函数 ^^ "<<endl;
T2 tmp = x *x + y * y + x * y;
return tmp;
}
template <typename T>
T fun(T x , T y , T z)
{
cout<<"调用了三个参数的 fun 函数 ^^ "<<endl;
T tmp = x * x + y * y + z * z + x * y * z;
return tmp;
}
int main()
{
int x1 = 1 , y1 = 4 , z1 = 5;
float x2 = 1.1 , y2 = 2.2;
double x3 = 2.0 , y3 = 3.1;
cout<<fun(x1,y1)<<endl;
cout<<fun(x2,y2)<<endl;
cout<<fun(x3,y3)<<endl;
cout<<fun(x1,y2)<<endl;
cout<<fun(x1,y1,z1)<<endl;
return 0;
}
</div>
运行结果:
从结果已经能看出来模版函数的重载是没有任何问题的了。那么模板函数和非模板函数之间是否能够重载呢??
using namespace std;
template <typename T>
T fun(T x,T y)
{
cout<<"调用了模板函数 ^^ "<<endl;
T tmp = x * x + y * y + x * y;
return tmp;
}
int fun(int x,int y)
{
cout<<"调用了非模板函数 ^^ "<<endl;
int tmp = x * x + y * y + x * y;
return tmp;
}
int main()
{
int x1 = 1 , y1 = 4;
float x2 = 1.1 , y2 = 2.2;
cout<<fun(x1,y1)<<endl;
cout<<fun(x2,y2)<<endl;
return 0;
}
</div>
运行结果:
看以看出模版函数和非模板函数也是可能重载的,那么重载函数的调用顺序是怎么样的呢?实际上是先查找非模板函数,要有严格匹配的非模板函数,就调用非模板函数,找不到适合的非模板函数在和模板函数进行匹配。
到这里,关于模板就说这些吧~~~~
3.模板类
要是理解了模版函数,模板类就相当的简单了,只不过模版函数是对函数中的类型使用模板,而模板类是对类中的类型使用模板,这我就不多说了,下面的代码是我以前利用模板写的单链表,这个是模板的典型应用:(测试过)
template <class T>
struct SLNode
{
T data;
SLNode<T> *next;
SLNode(SLNode<T&