函数模板
1.有两个类型参数的函数模板
2.在template语句与函数模板定义之间不允许有别的语句
3.同一函数模板实例化后的所有模板函数都必须执行相同的操作
4.函数模板也可以重载
5.函数模板与同名的非模板函数可以重载,这种情况下,调用时先找参数完全匹配的非模板函数, 如果找不到就调用匹配的模板函数。
在排序函数里可以使用函数模板,可以排序不同类型的数据
函数模板不支持模板形参默认值
模板最适合做数据结构与算法,类模板与函数模板配合使用
例子1:
template<typename T>
//int i; //错误,在template语句与函数模板定义之间不允许有别的语句
T max(T x,T y) { return (x>y)?x:y; }
template<typename T> //模板重载
T max(T x,T y,T z)
{
T t;
t=(x>y)?x:y;
return (t>z)?t:z;
}
int main()
{
int m=10,n=20;
double a=10.1,b=20.2,c=30.3;
cout<<max(m,n)<<endl; // 10 20
cout<<max(a,b,c)<<endl; //10.1 20.2
return 0;
}
例子1:模板排序函数
#include <algorithm> //该头文件包含了一些算法,诸如排序,最大值最小值之类,加上这个头文件,就可以直接用里面的算法
using std::swap;
//一般的排序
template <typename T>
void sort(T a[], int n)
{
for(int i=0; i<n-1; i++)
{
int min = i;
for(int j=i+1; j<n; j++)
if(a[j]<a[min])
min = j;
swap(a[min],a[i]);
}
}
//函数模板特化
#include <cstring>
template <>
void sort(const char* a[], int n)
{
for(int i=0; i<n-1; i++)
{
int min = i;
for(int j=i+1; j<n; j++)
if(strcmp(a[j],a[min])<0)
min = j;
swap(a[min],a[i]);
}
}
//指针类型特化的排序
template <typename T>
void sort(T* a[], int n)
{
for(int i=0; i<n-1; i++)
{
int min = i;
for(int j=i+1; j<n; j++)
if(*a[j]<*a[min])
min = j;
swap(a[min],a[i]);
}
}
//给结构类型排序
#include <iostream>
using namespace std;
struct Date
{
int y, m, d;
//Date(int y, int m, int d):y(y),m(m),d(d){}
};
bool operator<(const Date& a, const Date& b)
{
return (a.y<b.y||a.y==b.y&&(a.m<b.m||a.m==b.m&&a.d<b.d));
}
ostream& operator<<(ostream& o, const Date& d)
{
return o << d.y << '-' << d.m << '-' << d.d;
}
//输出数组元素的内容
template <class T>
void show(T a[], int n)
{
for(int i=0; i<n; i++)
cout << a[i] << ' ';
cout << endl;
}
/*template <typename T, int N>
//void show(T& t)
//{
// int n = sizeof(t)/sizeof(t[0]);
// for(int i=0; i<n; i++)
// cout << t[i] << ' ';
// cout << endl;
//}*/
//输出数组元素的内容
template <typename T, int N>
void show(T(&t)[N])
{
for(int i=0; i<N; i++)
cout << t[i] << ' ';
cout << endl;
}
template <typename T, int N>
void show(T*(&t)[N])
{
for(int i=0; i<N; i++)
cout << *t[i] << ' ';
cout << endl;
}
//输出一般类型的变量
template <typename T>
void show(T data)
{
cout << data << endl;
}
int main()
{
double m=123.4;
show(m);
int a[5]={6,1,9,2,8};
double d[4]={3.3,5.5,2.2,1.6};
Date x[3]={{2010,9,30},{2010,9,9},{2010,8,8}};
sort(a,5);//a==>int*
// sort(reinterpret_cast<int*>(d),4);
sort(d,4);
sort(x,3); //结构类型排序
show(a,5);show(d,4);show(x,3);
show(a);show(d);show(x);
const char* s[3]={"furong","quange","chunge"};
sort(s,3); //使用函数模板特化
show(s);
//指针类型的特化
int* ap[4]={new int(5),new int(2),new int(9),new int(8)};
double* bp[3]={new double(3.3),new double(5.5),new double(2.2)};
sort(ap,4);sort(bp,3);
show(ap);show(bp);
}
例子2:简单的特化程序
template <typename T>
const T& Min(const T& a, const T& b)
{ cout<<'A';return a<b?a:b; }
const char* Min(const char* a, const char* b)
{ cout<<'D';return strcmp(a,b)<0?a:b; }
template <typename T>
T& Min(T& a, T& b)
{ cout<<'B';return a<b?a:b; }
template <typename T, typename U>
T Min(const T& a, const U& b)
{ cout<<'C';return a<b?a:T(b); }
template <typename T>
T Min(const T& a, char b)
{ cout<<'E';return a<b?a:T(b); }
template <>
double& Min(double& a, double& b)
{ cout<<'F';return a<b?a:b; }
int main()
{
int m=20, n=10;
double x=1.1, y=2.2;
cout << Min(m,n) << endl;
cout << Min(x,y) << endl;
cout << Min(30,40) << endl;
cout << Min(5.9,6) << endl;
cout << Min("hello","world") << endl;
cout << Min<>("hello","world") << endl;
cout << Min(123,'x') << endl;
}
例子:autoptr模板
template <typename T>
class autoptr
{
T* p;
public:
autoptr(T* p):p(p){}
~autoptr(){delete p;}
autoptr(autoptr& a):p(0){operator=(a);}
autoptr& operator=(autoptr& a)
{
if(this==&a) return *this;
if(p!=NULL) delete p;
p = a.p;
a.p = NULL;
return *this;
}
T& operator*()const{return *p;}
T* operator->()const{return p;}
};
class A
{
int data;
public:
A(int d):data(d){cout<<this<<"A("<<d<<")"<<endl;}
~A(){cout<<this<<"~A()"<<data<<endl;}
void show()const{cout<<this<<":"<<data<<endl;}
};
int main()
{
autoptr<A> p(new A(10));
p->show(); //输出10
autoptr<A> q(p);
//p->show();出错,p已经没有动态内存的所有权了
q->show();
autoptr<A> r(new A(20));
(*r).show();
r = q;
}
1.有两个类型参数的函数模板
2.在template语句与函数模板定义之间不允许有别的语句
3.同一函数模板实例化后的所有模板函数都必须执行相同的操作
4.函数模板也可以重载
5.函数模板与同名的非模板函数可以重载,这种情况下,调用时先找参数完全匹配的非模板函数, 如果找不到就调用匹配的模板函数。
在排序函数里可以使用函数模板,可以排序不同类型的数据
函数模板不支持模板形参默认值
模板最适合做数据结构与算法,类模板与函数模板配合使用
例子1:
template<typename T>
//int i; //错误,在template语句与函数模板定义之间不允许有别的语句
T max(T x,T y) { return (x>y)?x:y; }
template<typename T> //模板重载
T max(T x,T y,T z)
{
T t;
t=(x>y)?x:y;
return (t>z)?t:z;
}
int main()
{
int m=10,n=20;
double a=10.1,b=20.2,c=30.3;
cout<<max(m,n)<<endl; // 10 20
cout<<max(a,b,c)<<endl; //10.1 20.2
return 0;
}
例子1:模板排序函数
#include <algorithm> //该头文件包含了一些算法,诸如排序,最大值最小值之类,加上这个头文件,就可以直接用里面的算法
using std::swap;
//一般的排序
template <typename T>
void sort(T a[], int n)
{
for(int i=0; i<n-1; i++)
{
int min = i;
for(int j=i+1; j<n; j++)
if(a[j]<a[min])
min = j;
swap(a[min],a[i]);
}
}
//函数模板特化
#include <cstring>
template <>
void sort(const char* a[], int n)
{
for(int i=0; i<n-1; i++)
{
int min = i;
for(int j=i+1; j<n; j++)
if(strcmp(a[j],a[min])<0)
min = j;
swap(a[min],a[i]);
}
}
//指针类型特化的排序
template <typename T>
void sort(T* a[], int n)
{
for(int i=0; i<n-1; i++)
{
int min = i;
for(int j=i+1; j<n; j++)
if(*a[j]<*a[min])
min = j;
swap(a[min],a[i]);
}
}
//给结构类型排序
#include <iostream>
using namespace std;
struct Date
{
int y, m, d;
//Date(int y, int m, int d):y(y),m(m),d(d){}
};
bool operator<(const Date& a, const Date& b)
{
return (a.y<b.y||a.y==b.y&&(a.m<b.m||a.m==b.m&&a.d<b.d));
}
ostream& operator<<(ostream& o, const Date& d)
{
return o << d.y << '-' << d.m << '-' << d.d;
}
//输出数组元素的内容
template <class T>
void show(T a[], int n)
{
for(int i=0; i<n; i++)
cout << a[i] << ' ';
cout << endl;
}
/*template <typename T, int N>
//void show(T& t)
//{
// int n = sizeof(t)/sizeof(t[0]);
// for(int i=0; i<n; i++)
// cout << t[i] << ' ';
// cout << endl;
//}*/
//输出数组元素的内容
template <typename T, int N>
void show(T(&t)[N])
{
for(int i=0; i<N; i++)
cout << t[i] << ' ';
cout << endl;
}
template <typename T, int N>
void show(T*(&t)[N])
{
for(int i=0; i<N; i++)
cout << *t[i] << ' ';
cout << endl;
}
//输出一般类型的变量
template <typename T>
void show(T data)
{
cout << data << endl;
}
int main()
{
double m=123.4;
show(m);
int a[5]={6,1,9,2,8};
double d[4]={3.3,5.5,2.2,1.6};
Date x[3]={{2010,9,30},{2010,9,9},{2010,8,8}};
sort(a,5);//a==>int*
// sort(reinterpret_cast<int*>(d),4);
sort(d,4);
sort(x,3); //结构类型排序
show(a,5);show(d,4);show(x,3);
show(a);show(d);show(x);
const char* s[3]={"furong","quange","chunge"};
sort(s,3); //使用函数模板特化
show(s);
//指针类型的特化
int* ap[4]={new int(5),new int(2),new int(9),new int(8)};
double* bp[3]={new double(3.3),new double(5.5),new double(2.2)};
sort(ap,4);sort(bp,3);
show(ap);show(bp);
}
例子2:简单的特化程序
template <typename T>
const T& Min(const T& a, const T& b)
{ cout<<'A';return a<b?a:b; }
const char* Min(const char* a, const char* b)
{ cout<<'D';return strcmp(a,b)<0?a:b; }
template <typename T>
T& Min(T& a, T& b)
{ cout<<'B';return a<b?a:b; }
template <typename T, typename U>
T Min(const T& a, const U& b)
{ cout<<'C';return a<b?a:T(b); }
template <typename T>
T Min(const T& a, char b)
{ cout<<'E';return a<b?a:T(b); }
template <>
double& Min(double& a, double& b)
{ cout<<'F';return a<b?a:b; }
int main()
{
int m=20, n=10;
double x=1.1, y=2.2;
cout << Min(m,n) << endl;
cout << Min(x,y) << endl;
cout << Min(30,40) << endl;
cout << Min(5.9,6) << endl;
cout << Min("hello","world") << endl;
cout << Min<>("hello","world") << endl;
cout << Min(123,'x') << endl;
}
例子:autoptr模板
template <typename T>
class autoptr
{
T* p;
public:
autoptr(T* p):p(p){}
~autoptr(){delete p;}
autoptr(autoptr& a):p(0){operator=(a);}
autoptr& operator=(autoptr& a)
{
if(this==&a) return *this;
if(p!=NULL) delete p;
p = a.p;
a.p = NULL;
return *this;
}
T& operator*()const{return *p;}
T* operator->()const{return p;}
};
class A
{
int data;
public:
A(int d):data(d){cout<<this<<"A("<<d<<")"<<endl;}
~A(){cout<<this<<"~A()"<<data<<endl;}
void show()const{cout<<this<<":"<<data<<endl;}
};
int main()
{
autoptr<A> p(new A(10));
p->show(); //输出10
autoptr<A> q(p);
//p->show();出错,p已经没有动态内存的所有权了
q->show();
autoptr<A> r(new A(20));
(*r).show();
r = q;
}