template <typename T> ...//建议
template <class T> ...
inline函数模板:
template <typename T> inline T max(const T&,const T&);
函数模板:
template <typename T>
int compare(const T& v1,const T& v2)
{
if(v1<v2) return -1;
if(v2<v1) return 1;//这里最好用<,因为只涉及到一个'<'符号的重载
return 0;
}
函数模板的使用:
int main()
{
cout<<compare(1,0)<<endl;//T is int;
string s1="hi",s2="world";
cout<<compare(s1,s2)<<endl;//T is string
}
类模板:
template <typename Type> class Queue{
public:
Queue();
Type &front();
//...
private:
//...
};
类模板的使用:
Queue<int> qi; //type is int;
Queue<vector<double>> qc; //type is vector<double>
模板形参不能重复定义:
template <typename V,typename V> V max(const V&,const V&);//error
也不能省略定义:
template <typename V1, V2> V1 max(const V1&,const V2&);//error
很有趣的一个例子:
template <typename T,size_t N> void array_init(T (&parm)[N])
{
for(size_t i=0;i!=N;++i)
{
parm[i]=0;
}
}
使用:
int x[42];
double y[40];
array_init(x);
array_init(y); //有意思的是,数组大小也被传进去了
下面2中方法的使用:
template <typename T> T fobj(T,T);
template <typename T> T fref(const T&,const T&);
...
int a[10],b[42];
fobj(a,b); //ok,call fobj(int*,int*)
fref(a,b); //error,arguments aren't converted to pointer
用模板初始化函数指针:
template <typename T> int compare(const T&,const T&);
...
int (*pf)(const int&,const int&)=compare;
初始化的时候必须注意唯一性(确定性):
void func(int (*)(const string&,const string&));
void func(int (*)(const int&,const int&));
...
func(compare);//error:which instantiation of compare?
返回类型中使用模板参数的一个习惯问题:
template <typename T1,typename T2,typename T3>
T1 sum(T2,T3);//建议,因为模板参数匹配是从左到右的
long val=sum<long>(i,lng);//可以省略T2,T1的说明
...
T3 sum(T2,T1);
long val=sum<long,int,long>(i,lng);//必须说明所有的模板参数
类外部定义成员模板:
template <typename T> template <typename V>
void Queue<T>::assign(V beg,V end){
//...
}
一个完整的Queue类:
template <typename Type> class Queue;
template <typename T>
std::ostream& operator<<(std::ostream&,const Queue<T>&);
template <typename Type> class QueueItem{
friend class Queue<Type>;
friend std::ostream& operator<< <Type>(std::ostream&,const Queue<T>&);
QueueItem(const Type &t):item(t),next(0){}
Type item;
QueueItem *next;
};
template <typename Type> class Queue{
friend std::ostream& operator<< <Type>(std::ostream&,const Queue<T>&);
public:
Queue():head(0),tail(0){}
template <typename T> Queue(T beg,T end):head(0),tail(0){ copy_elems(beg,end);}
Queue(const Queue &q):head(0),tail(0){ copy_elems(q)}
Queue& operator=(const Queue&);
~Queue(){ destroy();}
template <typename T> viod assign(T,T);
Type& front() { return head->item;}
const Type &front() const { return head->item;}
void push(const Type&);
void pop();
bool empty() const { return head==0;}
private:
QueueItem<Type> *head;
QueueItem<Type> *tail;
void destroy();
void copy_elems(const Queue&);
template <T> void copy_elems(T,T);
};
//另外,还有一些模板特化的问题,属于高级主题