• 非类型模板参数


    对于函数模板与类模板,模板参数并不局限于类型,普通值也可以作为模板参数。在基于类型参数的模板中,你定义了一些具体的细节来加以确定代码,直到代码被调用时这些细节才被真正的确定。但是在这里,我们面对的是这些细节是值,而不是类型,当要使用基于值的模板时,必须显式地指定这些值,才能够对模板进行实例化。

    非类型的类模板参数

    创建类的头文件

    #include<stdexcept>
    #include<iostream>
    using namespace std;
    
    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 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 out_of_range("Stack<>::pop(): stack is full");
        }
        --numElems;
    }
    
    template<typename T, int MAXSIZE>
    T Stack<T, MAXSIZE>::top() const
    {
        if(numElems <= 0) {
            throw out_of_range("Stack<>::top(): stack is full");
        }
        return elems[numElems - 1];
    }

    #include<stdexcept>
    #include<iostream>
    using namespace std;
    
    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 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 out_of_range("Stack<>::pop(): stack is full");
        }
        --numElems;
    }
    
    template<typename T, int MAXSIZE>
    T Stack<T, MAXSIZE>::top() const
    {
        if(numElems <= 0) {
            throw out_of_range("Stack<>::top(): stack is full");
        }
        return elems[numElems - 1];
    }

    实现代码:

    #include<iostream>
    #include<vector>
    #include<deque>
    #include<stdexcept>
    #include<string>
    #include<cstdlib>
    #include "stack4.h"
    using namespace std;
    
    
    int main()
    {
        try {
            Stack<int, 20> int20Stack;
            Stack<int, 40> int40Stack;
            Stack<string, 40> stringStack;
            
            int20Stack.push(7);
            cout<<int20Stack.top()<<endl;
            int20Stack.pop();
    
            stringStack.push("hello");
            cout<<stringStack.top()<<endl;
            stringStack.pop();
            stringStack.pop();
        }
        catch(exception const& ex) {
            cerr<<"Exception: "<<ex.what()<<endl;
            //return EXIT_FAILURE;
        }
        
        cin.get();  
        return 0;
    }

    #include<iostream>
    #include<vector>
    #include<deque>
    #include<stdexcept>
    #include<string>
    #include<cstdlib>
    #include "stack4.h"
    using namespace std;
    
    
    int main()
    {
        try {
            Stack<int, 20> int20Stack;
            Stack<int, 40> int40Stack;
            Stack<string, 40> stringStack;
            
            int20Stack.push(7);
            cout<<int20Stack.top()<<endl;
            int20Stack.pop();
    
            stringStack.push("hello");
            cout<<stringStack.top()<<endl;
            stringStack.pop();
            stringStack.pop();
        }
        catch(exception const& ex) {
            cerr<<"Exception: "<<ex.what()<<endl;
            //return EXIT_FAILURE;
        }
        
        cin.get();  
        return 0;
    }

    MAXSIZE是新加入的第二个模板参数,类型为int,它指定了数组最多可包含的栈元素的个数
    同样,我们可以为模板参数指定缺省值:

    template<typename T = int, int MAXSIZE = 100>
    class Stack {
        ...
    };
    

      非类型的函数模板参数

    你也可以为函数模板定义非类型参数。例如:

    template<typename T, int VAL>
    T addValue(T const& x)
    {
        return x + VAL:
    }

    借助于STL,可以传递这个函数模板的实例化给集中的每一个元素,让他们都增加一个整数值:

    std::transform(source.begin(), source.end(), dest.begin(), (int(*)(int const&))addValue<int, 5>);
    

      非类型模板参数的限制

    非类型模板参数是有限制的,通常而言,它们可以是常整数(包括枚举值)或者指向外部链接对象的指针。

    浮点数和类对象是不允许作为非类型模板参数的:

    template<double VAT>
    double process(double v) //error
    {
        return V * VAT;
    }
    
    template<string name>  //error
    class MyClass {
        ...
    };

      另外,你也不能使用全局指针作为模板参数

    template<char const* name>
    class MyClass{
        ...
    };
    
    char const* s = "hello";
    MyClass<s> x;   //s是一个指向内部连接对象的指针

    但是你可以这样使用:

    template<char const* name>
    class MyClass {
        ...
    };
    
    extern char const s[] = "hello";
    MyClass<s> x;  //OK

    全局字符数组s由"hello"初始化,是一个外部链接对象

  • 相关阅读:
    代码整洁之道读书笔记 1
    PhoneGap开发环境搭建
    Android + Eclipse + PhoneGap 2.9.0 安卓最新环境配置,部分资料整合网上资料,已成功安装.
    Oracle只读用户角色的建立
    linux系统下创建oracle表空间和用户权限查询
    Extjs的grid的单元格中加载超链接和按钮
    从网上找的Android实用代码,记录备用
    Android上实现各种风格的隐藏菜单,比如左右滑动菜单、上下滑动显示隐藏菜单
    android highcharts 柱状图例子
    web打印控件Lodop轻松输出清晰的图表和条码
  • 原文地址:https://www.cnblogs.com/wuchanming/p/4059941.html
Copyright © 2020-2023  润新知