前面的例子中,我们分别使用了类型和模板作为类模板的参数。除此之外,模板还支持非类型模板参数。
如下用数组实现Stack模板,第二个模板参数是一个int型常量,用于定义数组的最大长度。
template<typename T, int MAX_SIZE>
struct Stack
{
void push(const T&);
T pop();
private:
T elems[MAX_SIZE];
int size;
};
一般来说,模板的非类型参数只能是整型常量(包括enum),或者指向外部链接的指针(包括函数指针,类的成员函数指针)。到目前为止还不支持浮点数,对于字符串常量也不支持,但是可以支持具有外部链接的字符串常量指针。
例如对于下面的模板定义:
template<const char* MyName>
struct Token
{
std::string name{MyName};
};
下面的用法都会产生编译错误:
Token<“Hello”> tocken;
const char* str = "Hello";
Token<str> tocken;
而如下是可以正确编译通过的:
extern const char str[] = "Hello";
Token<str> token;
std::cout << tocken.name << std::endl;
总结一下,模板的参数支持以下类型:
类型参数;
使用typename或者class指示。非类型参数;
整型常量(包括enum),或者指向外部链接的指针(包括函数指针、类的成员函数指针,以及具有外部链接的字符串常量指针)。模板参数;
使用template<...> class XXX
的形式指示。