对于函数模板与类模板,模板参数并不局限于类型,普通值也可以作为模板参数。在基于类型参数的模板中,你定义了一些具体的细节来加以确定代码,直到代码被调用时这些细节才被真正的确定。但是在这里,我们面对的是这些细节是值,而不是类型,当要使用基于值的模板时,必须显式地指定这些值,才能够对模板进行实例化。
本文地址:,转载请注明源地址。
在上篇文章()中我们介绍了一个stack类模板作为例子,下面将看一个新版本的stack模板,来叙述本文将要介绍的特性:
非类型的类模板参数
创建类的头文件
#include#include using namespace std;template class Stack{private: T elems[MAXSIZE]; int numElems;public: Stack(); void push(T const&); void pop(); T top() const; bool empty() const { return numElems == 0; } bool full() const { return numElems == MAXSIZE; }};template Stack ::Stack():numElems(0) {}template void Stack ::push(T const& elem){ if(numElems == MAXSIZE) { throw out_of_range("Stack<>::push(): stack is full"); } elems[numElems] = elem; ++numElems;}template void Stack ::pop(){ if(numElems <= 0) { throw out_of_range("Stack<>::pop(): stack is full"); } --numElems;}template T Stack ::top() const{ if(numElems <= 0) { throw out_of_range("Stack<>::top(): stack is full"); } return elems[numElems - 1];}
实现代码:
#include#include #include #include #include #include #include "stack4.h"using namespace std;int main(){ try { Stack int20Stack; Stack int40Stack; Stack stringStack; int20Stack.push(7); cout< <
MAXSIZE是新加入的第二个模板参数,类型为int,它指定了数组最多可包含的栈元素的个数
同样,我们可以为模板参数指定缺省值:templateclass Stack { ...};
非类型的函数模板参数
你也可以为函数模板定义非类型参数。例如:
templateT addValue(T const& x){ return x + VAL:}
借助于STL,可以传递这个函数模板的实例化给集中的每一个元素,让他们都增加一个整数值:
std::transform(source.begin(), source.end(), dest.begin(), (int(*)(int const&))addValue);
非类型模板参数的限制
非类型模板参数是有限制的,通常而言,它们可以是常整数(包括枚举值)或者指向外部链接对象的指针。
浮点数和类对象是不允许作为非类型模板参数的:
templatedouble process(double v) //error{ return V * VAT;}template //errorclass MyClass { ...};
另外,你也不能使用全局指针作为模板参数:
templateclass MyClass{ ...};char const* s = "hello";MyClass x; //s是一个指向内部连接对象的指针
但是你可以这样使用:
templateclass MyClass { ...};extern char const s[] = "hello";MyClass x; //OK
全局字符数组s由"hello"初始化,是一个外部链接对象