非类型模板参数
模板参数分为:类型模板参数和非类型模板参数
类型模板参数:出现在模板参数列表中能够,跟在class和typename之后。
非类型模板参数:就是用一个常量来作为类或者函数模板的参数,在类或者函数模板中可将该参数当成常量来使用。
template<class T, size_t N>//(T为类型模板参数,N为非类型模板参数)
class array
{
public:
void push_back(const T& data)
{
// N = 10;
_array[_size++] = data;
}
T& operator[](size_t index)
{
assert(index < _size);
return _array[index];
}
bool empty()const
{
return 0 == _size;
}
size_t size()const
{
return _size;
}
private:
T _array[N];
size_t _size;
};
注意:
1.浮点数、类对象、字符串以及自定义类型都不允许作为非类型模板参数。
2.非类型模板参数必须在编译阶段就确认结果,否则编译器无法进行判断非类型模板参数的具体类型。
模板的特化
特化的概念:
使用模板可以实现与模板参数类型无关的功能,但对于一些特殊的模板参数类型(char*),可能会得到一些错误的答案,所以就要模板的特化。就是在原来的模板基础上,针对特殊类型进行的特殊化的实现方式。
模板的特化分为:函数模板特化、类模板的特化
函数模板特化:
template<class T>
T& Max(T& left,T& right)
{
return left>right?left:right;
}
template<>
char*& Max<char*>(char*& left,char*& right)
{
if(strcmp(left,right)>0
{
return left;
}
else
return right;
}
由上面代码我们可以知道:
函数模板的特化步骤:
1.先需要一个基础的函数模板;
2.再写一个函数模板,参数为空,后面跟一对空的尖括号;(template<>)
3.函数名后面需要一个尖括号,里面放需要特化的类型;
4.函数形参表中:类型必须和函数名后尖括号类型相同。
补充: 一般情况下不需要进行函数模板的特化,可以直接将特殊类型的普通函数给出即可。(原因:1.函数模板特化难度较大2.直接给出特殊类型的函数,简单且不容易出错)。
类模板的特化:
类模板的特化分为:全特化和偏特化。
全特化
就是将模板参数列表中的参数全部确定。