非类型模板参数
之前的模板博客中提到了模板作为C++进行泛型编程的一种方式,它可以定义类型形参,使用时会自动识别为需要的类型或者显式实例化。但是模板还有一种非类型参数,他和类型形参的区别是什么呢?
类型形参即为出现在模板参数列表中,跟在class或者typename之类的参数类型名称。
而非类型形参,就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用。
代码示例如下:
template<class T,size_t N = 10>//非类型模板参数,定义的是一个常量,必须是整形常量
class MyStack
{
public:
MyStack(const T& x = 0)
{
printf("%d\n", N);
}
private:
T _a[N];
size_t _top;
};
int main()
{
MyStack<int> st0;
MyStack<int, 100> st1;
MyStack<int, 200> st2;
return 0;
}
这里可以看到,其中定义的非类型模板参数N可以传入缺省值,也可以自己显式实例化,作用可以类比于define一个常量,但是要注意以下两点
注意事项
- 浮点数、类对象以及字符串是不允许作为非类型模板参数的。
- 非类型的模板参数必须在编译期就能确认结果。
模板的特化
使用场景
通常情况下,模板可以适应各种类型的代码也就是支持泛型编程,但是有些时候对于某种特殊的类型可能会出错,例如如下代码,在比较大小的函数中,传入内置类型的参数时,运行正常,但是如果传入的是自定义类型例如日期类或者字符串类型,那么比较结果可能会出现问题。
template<class T>
bool IsEqual(const T& left, const T& right)
{
return left == right;
}
int main()
{
cout << IsEqual(1, 2) << endl;
char p1[] = "hello";
char p2[] = "hello";
cout << IsEqual</