1、函数模版
(1) 定义:
template<typename T>
int compare(const T &v1,const T &v2)
{
if(v1<v2) return -1;
if(v2<v1) return 1;
}
模版定义以关键字template开始,后接模版形参表。模版形参可以是表示类型的类型形参(如上图的T),也可以是表示常量表达式的非类型形参。
(2) 实例化
使用函数模版时,编译器通常会为我们推断模版实参。要确定应该实例化哪个函数,编译器会查看每个实参。如果相应形参声明为类型形参的类型,则编译器从实参的类型推断形参的类型。如:
int main()
{
compare(1,0); //ok:binds template parameter to int
compare(3.14,2.7); //ok:bins template parameter to double
return 0;
}
2、类模板
(1)定义:
template<class Type> class Queue<const &Type>{
public:
Queue();
Type &front();
const Type &front() const;
void push(const &Type);
void pop();
private:
//...
}
类模板也必须以关键字template开头,后接模版形参表。
(2)实例化
要使用类模板,就必须显式指定模版实参:
Queue qs;//error:no template instantiation.
模版实参必须在用逗号分隔并用尖括号括住的列表中指定:
Queue<int> qi;//ok
Queue<string> qs;//ok
3、函数模版特化
在compare函数中,如果用两个const char*实参调用这个模版定义,函数将比较指针值,而不是字符串。所以,需要用到函数模版特化。
(1)函数模版特化
函数模版特化形式如下:
template<>//关键字template后接一对空的尖括号(<>)
int compare<const char*>(cosnt char* const &v1,const char* const v2)//尖括号中指定特化的模版形参
{
return strcmp(v1,v2);
}
(2)函数重载在特化中省略空的模版形参表template<>,则结果是声明该函数的重载非模版版本:
int compare(const char* const&,const char* const&);
4、类模版特化类模板特化分为3种:定义类特化、特化成员而不特化类、类模板的部分特化
(1)定义类特化
template<> class Queue<const char*>{
public:
Queue();
std::string &front();
const std::string &front() const;
void push(const char*);
void pop();
private:
Queue<std::string> real_queue; //...
}
void Queue<const char*>::push(const char* val)//在类特化外部定义成员时,成员前不能加template<>标记
{
return real_queue.push(val);
}
(2)特化成员而不特化类
除了特化整个模版外,还可以只特化其中的成员函数:
template<>
void Queue<const char*>::push(const char* const &val)
{
...
}
成员特化的声明与任何其他函数模版特化一样,必须以空的模版形参表开头。
5、类模板的部分特化
如果类模板有一个以上的模版形参,我们也许想特化某些形参而非全部,使用类模板的部分特化可以做到这一点:
template <class T1,class T2>
class some_template{
//...
};
template<class T1>
class some_template<T1,int>{
//...
}
类模版的部分特化本身也是模版。部分特化的模版形参表只列出未知模版实参的那些形参。像其他类模板一样,部分特化是在程序中使用时隐式实例化:
some_temlate<int,string> foo;//uses template
some_temlate<string,int> bar;//uses partial specialization
注:VC++6.0编译器不支持部分特化,编译会报错。