非类型的类模板参数

参考《C++ Templates》一书。ios

关于函数模板和类模板,模板参数并不局限于类型,普通值也能够做为模板参数数组

当要使用基于值的模板时,必须显式地指定这些值,才可以对模板进行实例化,并得到最终代码。函数

详细解释可参考一下代码:spa

stack4.hppcode

#ifndef _STACK4_H_
#define _STACK4_H_

#include <stdexcept>

/**
*   @class:栈的类模板
*   @param: typename T: 模板参数,栈存储元素的类型
*   @param:int MAXSIZE: 栈元素的最大个数
*   note:模板参数并不局限于类型,普通值也能够做为模板参数
*/
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<>::pop(): empty stack");
    return elems[numElems - 1];  //返回最后一个元素
}

#endif

main.cppblog

/************************************************************************
*   @filename: non-type template parameters
*   @author:   JackyLiu
*   @Date:     2013-6-26
*************************************************************************/

#include <iostream>
#include <string>
#include <cstdlib>
#include "stack4.hpp"

int main(int argc, char* argv[])
{
    try
    {
        Stack<int, 20> int20Stack;   //能够存储20个int元素的栈
        Stack<int, 40> int40Stack;   //能够存储40个int元素的栈
        Stack<std::string, 40> stringStack;  //能够存储40个string元素的栈

        //使用可存储20个int元素的栈
        int20Stack.push(7);
        std::cout << int20Stack.top() << std::endl;
        int20Stack.pop();

        //使用可存储40个string元素的栈
        stringStack.push("hello");
        std::cout << stringStack.top() << std::endl;
        stringStack.pop();
        stringStack.pop();
    }
    catch(std::exception const& ex)
    {
        std::cerr << "Exception: " << ex.what() << std::endl;

        int i;
        std::cin >> i;
        return EXIT_FAILURE;   //退出程序且有ERROR标记
    }
}

运行结果:ci