模板元编程之非类型模板参数(三)

一、简介

对于函数模板和类模板,模板参数并不局限于类型,普通值也可以作为模板参数,当要使用基于值的模板时,必须显示的指定这些值,才能够对模板进行实例化,并获得最终代码。

复制代码
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)作为实参

posted @   TechNomad  阅读(18)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示