前言
泛型是独立于任何特定类型的编码,在C++中,我们经常使用的容器vector,该容器可以定义不同种类的vector,如vector list、vector list或自定义类型等。
函数模板
如果要编写一个函数来比较两个数的大小,返回其中最大值,这两个数可以是int型,也可以是double型或者自定义类型等,要想用一个函数实现上述功能,则模板函数就派上用场了。
template <typename T>
T compare(const T& v1, const T& v2) {
if (v1 < v2) {
return v2;
}
return v1;
}
int main(int argc, char const *argv[])
{
int max = compare(23, 34);
cout<<"max = "<<max<<endl; //输出结果34
return 0;
}
上述代码中可以看到函数模板定义和使用方法,首先模板定义固定格式:
template <typename T> // 必须以template 开头,typename表示类型名,也可以用class替换,T表示形参,可以说随便命名。
使用的时候编译器会将具体使用的类型来替换掉"T",这里是用int替换掉"T"。
类模板
跟定义函数模板一样,也可以定义类模板。具体可以参考智能指针与引用计数详解(二)中的技术类模板定义:
template <typename T>
class U_Ptr {
private:
friend class HasPtr<T>;
U_Ptr(T *p);
~U_Ptr();
T *m_ip;
int m_useCount;
};
类模板也是模板,所以都是以template开头,后接模板形参表。不过使用的时候必须显示指定实参(尖括号里边的类型):
HasPtr<int> ptr(p, 20); // 显示指定实参为int
typename和class区别
在函数模板形参表中,关键字typename和class具有相同含义,可以互换使用,两个关键字都可以在同一模板形参表中使用:
template <typename T, class U> add(const T&, const U&);
使用关键字typename代替关键字class指定模板类型形参也许更为直观,毕竟,可以使用内置类型(非类类型)作为实际的类型形参,而且,typename更清楚地指明后面的名字是一个类型名。但是,关键字typename是作为标准C++的组成部分加入到C++中的,因此旧程序更有可能只用关键字class。