函数模板
编译器可以根据实参去猜测形参类型
函数模板不支持模板形参的默认值
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
template <typename T>
class Type{
public:
static string name(){
return typeid(T).name();
}
};
//完全特化
template <>
class Type<int>{
public:
static string name(){
return "I am int";
}
};
template <typename T>
class Type<T*>{
public:
static string name(){
return Type<T>::name() + " pointer";
}
};
template <typename T>
string type(T t){
return Type<T>::name();
}
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]);
}
}
struct Date{
int y,m,d;
};
ostream& operator << (ostream& o, Date d){
cout << d.y << " - " << d.m << " - " << d.d ;
return o;
}
bool operator < (Date d1, Date d2){
if(d1.y < d2.y)
return true;
if(d1.m < d2.m)
return true;
if(d1.d < d2.d)
return true;
return false;
}
//只有数组可以匹配上
//函数引用自动匹配参数的写法
template <typename T, int n>
void show(T (&t)[n]){
//int n1 = sizeof(t)/sizeof(t[0]);
int n1 = n;
for(int i=0; i<n1; i++){
cout << t[i] << " ";
}
cout << endl;
}
//只有单个字符可以匹配上
template <typename T>
void show(T &t){
cout << t << endl;
}
//指针数组的半特化
template <typename T, int n>
void show(T* (&t)[n]){
//int n1 = sizeof(t)/sizeof(t[0]);
int n1 = n;
for(int i=0; i<n1; i++){
cout << *t[i] << " ";
}
cout << endl;
}
int main (){
cout << Type<int*>::name() << endl;
cout << type(88) << endl;
int a = 90;
int* b = &a;
cout << type(b) << endl;
//通用模板排序
int aa[5] = {9, 3, 8, 2, 0};
sort(aa, 5);
for(int i=0; i<5; i++){
cout << aa[i] << " ";
}
cout << endl;
Date d[3] = {{2018,3,8}, {2010,9,17}, {2010,9,14}};
sort(d, 3);
for(int i=0; i<3; i++){
cout << d[i] << " ";
}
cout << endl;
show(d);
show(a);
double * d2[3] = {new double(1.1), new double(1.4), new double(1.6)};
show(d2);
getchar();
return 0;
}
Pair
用函数模板自动确定形参类型来实例化类
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
template <typename T, typename U>
struct Pair{
T first;
U second;
Pair():first(),second(){}
Pair(const T& a, const U& b):first(a),second(b){}
//类中的模板
template <typename X, typename Y>
Pair<T, U>& operator=(const Pair<X, Y>& p){//本类中所有的Pair 都有<T, U> ,可省略
first = conertTo<T>(p.first);
second = conertTo<U>(p.second);
return *first;
}
};
//注意,字符串需要特化,没写
template <typename To, typename From>
To convertTo(From v){
return (To)v;
}
template <typename T, typename U>
ostream& operator<<(ostream& o, const Pair<T, U>& p){
return o << p.first <<"; " << p.second << endl;
}
template <typename T, typename U>
Pair<T, U> makePair(T t, U u){
return Pair<T, U> (t, u);//匿名对象
}
int main (){
cout << Pair<string, int>("sdsd", 18);
cout << makePair("sdsd", 18);
getchar();
return 0;
}
autoptr
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
template <typename T>
class autoptr{
T* p;
public:
autoptr(T* p):p(p){}
~autoptr(){delete p;}
autoptr(autoptr& a){//构造函数,调用等号重载运算符函数实现
operator = (a);
}
autoptr& operator = (autoptr& a){
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 << "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();
autoptr<A> q(p);
q->show();
autoptr<A> r = new A(20);
r->show();
(*r).show();
getchar();
return 0;
}