一、简介
对于函数模板和类模板,模板参数并不局限于类型,普通值也可以作为模板参数,当要使用基于值的模板时,必须显示的指定这些值,才能够对模板进行实例化,并获得最终代码。
template <typename T, int MAXSIZE> 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 <typename T, int MAXSIZE> Stack<T, MAXSIZE>::Stack():numElems(0) { } template<typename T, int MAXSIZE> void Stack<T, MAXSIZE>::push(T const& elem) { if (numElems == MAXSIZE) { throw std::out_of_range("Stack<>::push():stack is full"); } elems[numElems] = elem; ++numElems; } template<typename T, int MAXSIZE> void Stack<T, MAXSIZE>::pop() { if (numElems <= 0) { throw std::out_of_range("Stack<>::pop():empty stack"); } --numElems; } template<typename T, int MAXSIZE> T Stack<T, MAXSIZE>::top() const { if (numElems <= 0) { throw std::out_of_range("Stack<>::top():empty stack"); } return elems[numElems - 1]; //返回最后一个元素 }
从上述示例中我们可以使用元素数目固定的数组来实现stack,这个方法(固定大小的数组)的优点是:无论是开发者来管理内存,还是由变猪容器来管理内存,都可以避免内存管理开销。
二、非类型的类模板参数的使用
int main() { Stack<int, 20> int_stack; //可以存储20个int元素的栈 int_stack.push(10); std::cout << int_stack.top() << std::endl; Stack<std::string, 40> string_stack; //可以存储40个int元素的栈 string_stack.push("hello"); std::cout << string_stack.top() << std::endl; return 0; }
三、非类型的函数模板参数的使用
我们也可以为函数模板定义非类型参数,例如下面的函数模板定义了一组用于增加特定值的函数
template<typename T, int VAL> T addValue(T const& x) { return x + VAL; }
四、非类型模板参数的限制
非类型模板参数是有限制的,通常而言,它们可以是常整数(包括枚举值),或者指向外部链接对象的指针。但是浮点数和类对象是不允许作为非类型模板参数的
template <double VAT> double process(double v) { return v * VAT; } template <std::string name> class MyClass { };
总结:
(1).模板可以具有值模板参数,而不仅仅是类型模板参数
(2).对于非类型模板camshaft,不能使用浮点数、class类型的对象和内部链接对象(如string)作为实参
标签:编程,Stack,numElems,参数,template,stack,之非,模板 From: https://www.cnblogs.com/TechNomad/p/17512730.html