template是针对“一个或者多个尚未明确的型别”所撰写的函数或类别,可以显示地(explicitly)或者隐式地(implicitly)将型别当做参数来传递。
template <class T>
inline const T& max (const T& a,const T& b)
{
return a<b?b:a;
}
非型别的模板参数 Nontype Templates
如可以把标准类别bitset<>的bits数量以template参数指定之:定义两个由bits构成的容器
bitset<32> flag32;
bitset<64> flag64;
缺省模板参数 Default Template Parameters
template <class T,class container=vector<T> >
class MyClass;
如果只传给它一个参数,那么缺省参数可作为第二个参数使用;
MyClass<int> x1;等效于
MyClass <int vector<int> > x1;
关键字typename
typename被用来作为型别之前的标识符号。
template <class T>
class MyClass{
typename T::SubType *ptr;//如果没有关键字typename,SunType会被认为是一个static成员。
};
SubType成为一个型别的条件是,任何一个用来取代T的型别,其内部必须提供一个内部型别SubType的定义。
MyClass<Q> x;
......
class Q{
typedef int SubType;//也可以是抽象数据类型(如class)
...
}
typename还可以在template声明中用来替换关键字class;
成员模板 Member Template
class member function可以是个template,但这样的member template既不能是virtual,也不可以有缺省参数。这种特性通常用来为template classs的成员提供自动型别转换。
template <class T>
class MyClass{
private:
T value;
public:
void assign(const MyClass& x){
value=x.value;
}
}
void f(){
MyClass<double> d;
MyClass<int> i;
d.assign(d);//OK
d.assign(i);//error使用不同的template型别会出错
};
更改为:
template <class T>
class MyClass{
private:
T value;
public:
template <class U>
void assign(const MyClass<U>& x){
value=x.getVaule();
}
T getValue() const{
return value;
}
};
void f(){
MyClass<double> d;
MyClass<int> i;
d.assign(d);//OK
d.assign(i);//OK
}
assign()的参数和*this的型别并不相同,所以不能直接存取MyClass<>的private成员和protected成员,取而代之,用类似于本例getValue()之类的东西。
Template constructor是member template的一种特殊形式。用于“在复制对象时实现隐式型别转换”。注意,template constructor并不遮掩implicit copy constructor。
template <class T>
class MyClass{
public:
template <class U>
MyClass (const MyClass<U>& x);
...
};
void f()
{
MyClass<double> xd;
MyClass<double> xd2(xd);//calls implicit copy constructor
MyClass<int> xi(xd);//calls template constructor
}
嵌套的模板类 Nested Template Classes
template <class T>
class MyClass{
...
template <class U>
class NestedClass;
...
}