172210704111-陈国佳总结《2017年12月30日》【连续080天】
标题:函数模板和类模板;
内容:
A.函数模板:
template<class 类型参数1,class 类型参数2,......>
返回值类型 模板名(形参表)
{
函数体
};
#include<iostream>
using namespace std;
template <class T>
void Swap(T&x,T&y)
{
T tmp=x;
x=y;
y=tmp;
}
int main()
{
int n=1,m=2;
Swap(n,m);
cout<<n<<" "<<m<<endl;
double f=1.2,g=2.3;
Swap(f,g);
cout<<f<<" "<<g<<endl;
return 0;
}
多个类型参数情况:
template <class T1,class T2>
T2 print(T1 arg1,T2 arg2)
{
cout<<arg1<<" "<<arg2<<endl;
return arg2;
}
求数组最大元素的MaxElement函数模板:
template <class T>
T MaxElement(T a[],int size)
{
T tmpMax =a[0];
for(int i=1;i<size;++i)
if(tmpMax<a[i])
tmpMax=a[i];
return tmpMax;
}
不通过参数实例化函数模板:
template<class T>
T Inc(T n)
{
return 1+n;
}
int main()
{
cout<<Inc<double>(4)/2;
return 0;
}
输出2.5;
函数模板可重载,只要形参表或类型形参表不同即可。
template<class T1,class T2>
void print(T1 arg1,T2 arg2){
cout<<arg1<<" "<<arg2<<endl;
}
template<class T>
void print(T arg1,T arg2){
cout<<arg1<<" "<<arg2<<endl;
}
template<class T,class T2>
void print(T arg1,T arg2){
cout<<arg1<<" "<<arg2<<endl;
}
编译器调用函数的次序:
1)先找参数完全匹配的普通函数;
2)再找参数完全匹配的模板函数;
3)再找实参数经过自动类型转换后能够匹配的普通函数;
4)报错;
匹配模板函数时,不进行类型自动转换:
即如果实参类型与参数表中不符,编译器不会作出把double转换成int之类的操作;
函数模板实例:Map
#include<iostream>
using namespace std;
template<class T,class Pred>
void Map(T s,T e,T x,Pred op){
for(; s!=e;++s,++x){
*x=op(*s);
}
}
int Cube(int x){
return x*x*x;
}
double Square(double x){
return x*x;
}
int a[5]={1,2,3,4,5},b[5];
double d[5]={1.1,2.1,3.1,4.1,5.1},c[5];
int main()
{
Map(a,a+5,b,Square);
for(int i=0;i<5;++i)cout<<b[i]<<",";
cout<<endl;
Map(a,a+5,b,Cube);
for(int i=0;i<5;++i)cout<<b[i]<<",";
cout<<endl;
Map(d,d+5,c,Square);
for(int i=0;i<5;++i)cout<<c[i]<<",";
cout<<endl;
return 0;
}
B.类模板:
template<class 类型参数1,class 类型参数2,.........>
class 类模板名
{ 成员函数和成员变量
};
注:上式还可写成template<typename 类型参数1,typename 类型参数2,......>
类模板成员函数写法:
template<class 类型参数1,class 类型参数2,.........>
返回值类型 类模板名<类型参数名列表>::成员函数名(参数表)
{
}
类模板定义对象写法:
类模板名<真实类型参数表>对象名(构造函数参数表);
Pair模板:
#include<iostream>
using namespace std;
template <class T1,class T2>
class Pair{
public:
T1 key;
T2 value;
Pair(T1 k,T2 v):key(k),value(v){ };
bool operator<(const Pair<T1,T2>&p)const;
};
template<class T1,class T2>
bool Pair<T1,T2>::operator<(const Pair<T1,T2>&p)const
{
return key<p.key;
}
int main()
{
Pair<string,int>student("Tom",19);
cout<<student.key<<" "<<student.value;
return 0;
}
同一个类模板的两个模板类是不兼容的;
函数模板作为类模板成员:
#include<iostream>
using namespace std;
template <class T>
class A{
public:
template<class T2>
void Func(T2 t){
cout<<t;
}
};
int main()
{
A<int> a;
a.Func('K');
a.Func("hello");
return 0;
}
类模板和非类型参数:
class CArray{
T array[size];
public:
void Print()
{
for(int i=0;i<size;++i)
cout<<array[i]<<endl;
}
};
int main()
{
CArray<double,40> a2;
CArray<int ,50>a3;
}
明日计划:学习;