模板可以分为两类:一个是函数模板,另一个是类模板。
一、函数模板
template <class/typename 形参名, class/typename 形参名, ......> 返回类型 函数名(参数列表)
{
函数体
}
#include <iostream>
template<class T> T getMax(T a, T b)
{
T result;
result = (a > b)? a : b;
return (result);
}
int main()
{
int i = 5, j = 8, k = 0;
long l = 800, m = 5000, n = 0;
k = getMax(i,j);
n = getMax(l,m);
std::cout<<"k = "<< k <<std::endl;
std::cout<<"n = "<< n <<std::endl;
return 0;
}
二、类模板
template <class/typename 形参名, class/typename 形参名, ......> class 类名
{
...
};
#include <iostream>
template<typename T1,typename T2>class myClass
{
private:
T1 iVaule;
T2 jValue;
public:
myClass(T1 a, T2 b); // constructor
void show();
};
template<typename T1, typename T2> myClass<T1, T2>::myClass(T1 a, T2 b):iVaule(a), jValue(b){}
template<typename T1, typename T2> void myClass<T1, T2>::show()
{
std::cout<<"iVaule = "<< iVaule <<", jValue = "<< jValue <<std::endl;
}
int main()
{
myClass<int, int> classOne(2, 6);
classOne.show();
myClass<double, char> classTwo(2.7, 'a');
classTwo.show();
}
三、模板的形参
模板的形参有三种类型:类型形参、非类型形参和模板形参
1、类型形参:
关键字class/typename + 类型形参名字
template<
class T> void func(T tmp){};
其中T就是一个类型形参,类型形参的名字可以随意定。
2、非类型形参:内置类型形参
template<class T,
int a> class B{};
其中int a就是非类型的模板形参。
非类型的模板形参只能是整型,指针和引用,像double, string这样的类型是不允许的。但double &, double *,对象的引用或指针是正确的。
(1)当模板的形参是整型时,调用该模板时的实参必须是整型的,且在编译期间是常量。
比如template<class T, int a>class A{}; 如果 int b,此时 A<int, b> m是错的,因为b不是常量。如果const int b,这是A<int, b> m就是正确的,因为b是常量。
(2)非类型形参一般不应用于函数模板中。
3、类模板的默认模板类型形参
可以为
类模板的
类型形参提供默认值,但不能为函数模板的类型形参提供默认值。可以为
函数模板和类模板的
非类型形参提供默认值。
template<class T1,
class T2 = int> class A{};
参考: