1. 非类型模板参数
模板参数主要分为两类:类型形参与非类型形参。类型形参就是我们在 template<class T> 里看到的那些,跟在 class 或 typename 后面的参数名。
非类型形参则不同,它允许我们传入一个常量值作为模板参数。在类或函数模板内部,这个参数可以像常量一样被使用。比如实现一个固定大小的静态数组模板:
namespace Achieve {
template<class T, size_t N = 10>
class Array {
public:
T& operator[](size_t index) { return _array[index]; }
const T& operator[](size_t index) const { return _array[index]; }
size_t size() const { return _size; }
bool empty() const { return _size == 0; }
private:
T _array[N];
size_t _size;
};
}
这里有两个关键点需要注意:
- 类型限制:浮点数、类对象以及字符串通常不允许作为非类型模板参数(只有整型、无符号整形、指针、引用等可以)。注意 C++20 开始支持
double等非类型模板参数,但旧标准下仅限整型。 - 编译期确定:非类型模板参数的值必须在编译期就能确认,不能是运行时的变量。
2. 模板的特化
通常情况下,模板能处理通用逻辑,但在某些特殊场景下,通用实现可能不符合预期,甚至产生错误。这时候就需要对模板进行特化。
2.1 概念
举个例子,如果我们写了一个通用的小于比较函数模板:
template<class T>
bool Less(T left, T right) {
left < right;
}


