080day(函数模板和类模板)

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;
}


明日计划:学习;





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值