您的位置:首页 > 编程语言 > C语言/C++

C++菜鸟学习笔记——模板与泛型编程

2011-05-11 23:26 495 查看
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)
)
{
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);

};

//另外,还有一些模板特化的问题,属于高级主题
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: