STL——函数模板

来源:互联网 发布:异或java 编辑:程序博客网 时间:2024/05/20 20:23
函数模板
  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;
}



















0 0