函数模版
模版的实例化
模版的函数
模版类形参
模版类非形参
模版实例化
模版的特例化
定义模版函数的参数的列表
template<typename T,class m>//尽量不要写class 防止和类混淆
bool compare(t a , t b)
{
...
}
使用函数模版的方法
compare<int >(a,b)函数模版实例化为模版函数
不过如何使用每次通过不同类型的模版函数都会在代码里生成新的一份。(编译器做这一工作
)
一般的模版实例化一个函数是隐式的(因为并不知到有该类型的东西)
显示实例化
template bool compare<int>(int, int);
模版函数如果不是用不会被编译(所以如果函数模版有错误就不会被发现)
模版的实例化推演 (类模版没有)
没有指定模版的参数编译器会自己选合适的模版函数去处理如果
默认的查找方式 非模版->模版->特例化
模版文件一般保存在头文件中
t=char *
模版的实例化的 T 参数是重定义的过程(例如 const t a) char * const a;
具体代码如下:
模版的特例化(特例化的前提首先应该有模版)
template<typename T>
int findData(T *array, int size, const T &val)
{
for(int i=0; i<size; ++i)
{
if(array[i] == val)
return i;
}
return -1;
}
//char*特例化版本
//“int findData(char **,int,const char *&)”不是函数模板的专用化
template<>
int findData(char**array, int size, char*const &val)
{
for(int i=0; i<size; ++i)
{
if(strcmp(array[i], val) == 0)
return i;
}
return -1;
}
对一些特殊的类型进行特别对待
template<>
保证函数样子与模版样子一样 参数换成自定义的类型
模版和模版特例化的过程中如果产生的形参如果是模版类型 尽量传递const 引用 (减少对自定义类型的生成吗、防止引用常量)(对于指针应该分清楚const 的修饰)
模版可以传递非类型参数
非类型参数一般都是常数
使用方法如下代码 template<typename T=int, int SIZE=10> 定义
使用的话SqStack<int, 90> stack1;
类模版注意的事项首先模版的作用域在类结束就结束了
如果要再次使用就需要重新定义
并且除过构造函数和析构函数其他函数都要制定类型(类外调用)
并且尽量采用常方法 若用改模版实例化一个常对象会出错
并且采用常引用 隐士生成的对象都是常对象
类的选择性实例化
//“Link<T>::Node”: 依赖名称不是类型
typename:
用来定义模板类型参数的
告诉编译器后面的名字是一个类型
template<typename T>
typename Link<T>::Node* Link<T>::queryNode(const T &value)const
{
Node *pcur = mphead->mpnext;
while(pcur != NULL)
{
if(pcur->mdata == val)
return pcur;
pcur = pcur->mpnext;
}
return NULL;
}
template<typename E>
Link<E>::Link():mphead(new Node){}
template<typename E>
Link<E>::~Link()
{
Node *pcur = mphead;
while(pcur != NULL)
{
mphead = mphead->mpnext;
delete pcur;
pcur = mphead;
}
}
template<typename T>
void Link<T>::insertHead(const T &val)
{
Node *pcur = new Node(val);
pcur->mpnext = mphead->mpnext;
mphead->mpnext = pcur;
}
template<typename T>
void Link<T>::show()
{
Node *pcur = mphead->mpnext;
while(pcur != NULL)
{
cout<<pcur->mdata<<" ";
pcur = pcur->mpnext;
}
}
int main()
{
//类模板的选择性实例化
Link<int> link1;
link1.insertHead(20);
link1.insertHead(4);
link1.insertHead(56);
link1.insertHead(12);
link1.insertHead(89);
cout<<link1.query(56)<<endl;
cout<<link1.query(13)<<endl;
Link<char*> link2;
link2.insertHead("aaa");
link2.insertHead("bbb");
link2.insertHead("ccc");
link2.insertHead("ddd");
// query<const char*>
// query<char*>
cout<<link2.query("ccc")<<endl;
char buf[]="ccc";
cout<<link2.query<char*>(buf)<<endl;
return 0;
}