能定义一种适用于不同类型对象的行为。
声明语法
template <parameter list>
template function/class declaration
template标志着模板声明的开始,接下来是模板参数列表。该列表包含关键字typename,它定义了一个模板参数objType,他是一个占位符,实例化模板时,将使用对象的类型替换他。
template <typename T1,typename T2>
bool TemplateFunction(const T1& param1,const T2& param2);
//模板对象
template <typename T1,typename T2=T1>
class MyTemplate{
private:
T1 member1;
T2 member2;
public:
T1 GetObj1(){return member1;}
};
模板函数
需要编写一个适用于不同类型参数的函数时可使用模板,如下用于返回参数较大值。
template <typename objType>
const objType& GetMax(const objType& value1,const objType& value2)
{
return value1>value2?value1:value2;
}
对于模板函数,可以不指定参数,因为编译器能够根据传入参数进行判断。对于模板类,需要显示指定参数。
模板类
需要在不同类中定义不同的参数时,可以使用模板。
template <typename T>
class HoldVarTypeT
{
private:
T value;
public:
void SetValue(const T& newValue){value=newValue;}
T& GetValue(){return value;}
};
模板的实例化和具体化
模板类是创建类的蓝图,仅当模板类被使用后,其代码才存在。对于定义了但未使用的模板类,编译器将忽略它。对于模板来说,实例化指的是使用一个或多个模板参数来创建特定的类型。
对于有些情况,使用特定的类型实例化模板时,需要显示地指定不同的行为,即为特定的类型指定行为。
模板类和静态成员
静态成员由该类的所有实例共享。模板类的静态成员与此类似,有特定具体化的所有实例共享。对于不同的实例类,他们会创建不同的实例变量。
参数数量可变的模板
如果需要编写一个函数,能够计算任意数量值的和,就需要使用参数数量可变的模板。
使用参数数量可变的模板的参数
template <typename Res,typename ValType>
void Sum(Res& result,ValType& val)
{
result=result+val;
}
template Sum<typename Res,typename First,typename... Rest>
void Sum(Res& result,First vall,Rest... valN)
{
result=result+vall;
return Sum(result,valN ...);
}
模板的省略号告诉编译器,默认类或模板函数可接受任意数量的模板参数,且这些参数可为任意类型。
使用static_assert执行编译阶段检查
static_assert可以在不满足指定条件时禁止编译,如你要禁止针对int实例化模板类,可使用static_assert,它是一种编译阶段断言,可用于在开发环境显示一条自定义消息:
static_assert(expression being validated,"Error message when check fails");
要禁止针对类型int实例化模板类,可使用static_assert(),并将sizeof(T)和sizeof(int)进行比较,如果相等,就显示一条错误信息:
static_assert(sizeof(T)!=sizeof(int),"No int please");