zoukankan      html  css  js  c++  java
  • c++ template学习总结3

    和往常一样,先来看一段代码:

    #include <stdexcept> 
    
    template <typename T, int MAXSIZE> 
    class Stack { 
      private: 
        T elems[MAXSIZE];        // elements 
        int numElems;            // current number of elements 
      public: 
        Stack();                 // constructor 
        void push(T const&);     // push element 
        void pop();              // pop element 
        T top() const;           // return top element 
        bool empty() const {     // return whether the stack is empty 
            return numElems == 0; 
        } 
        bool full() const {      // return whether the stack is full 
            return numElems == MAXSIZE; 
        } 
    }; 
    
    // constructor 
    template <typename T, int MAXSIZE> 
    Stack<T,MAXSIZE>::Stack () 
      : numElems(0)              // start with no elements 
    { 
        // nothing else to do 
    } 
    
    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;  // append element 
        ++numElems;              // increment number of elements 
    } 
    
    template<typename T, int MAXSIZE> 
    void Stack<T,MAXSIZE>::pop () 
    { 
        if (numElems <= 0) { 
            throw std::out_of_range("Stack<>::pop(): empty stack"); 
        } 
        --numElems;              // decrement number of elements 
    } 
    
    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];  // return last element 
    } 

    接下来编写我们的测试函数:

    #include <iostream> 
    #include <string> 
    #include <cstdlib> 
    #include "stack4.hpp" 
    
    int main() 
    { 
        try { 
            Stack<int,20>         int20Stack;    // stack of up to 20 ints 
            Stack<int,40>         int40Stack;    // stack of up to 40 ints 
            Stack<std::string,40> stringStack;   // stack of up to 40 strings 
    
            // manipulate stack of up to 20 ints 
            int20Stack.push(7); 
            std::cout << int20Stack.top() << std::endl; 
            int20Stack.pop(); 
    
            // manipulate stack of up to 40 strings 
            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; 
            return EXIT_FAILURE;  // exit program with ERROR status 
        } 
    } 

    大家要注意int20Stack和int40Stack是两个不同的类型,他们是不能进行硬是或者显示的转换的。也不能够相互赋值。

    你还可以为函数模板定义非型别参数:

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

    当我们想把【函数】和某种操作作为参数传递的时候,就非常有用,比如在使用STL时,你可能有下面的代码:

    std::transform (source.begin(), source.end(),  // start and end of source 
                    dest.begin(),                  // start of destination 
                    addValue<int,5>);              // operation 
    
    有时候我们为了使得编译器推导的时候简单一些,可以使用:
    std::transform (source.begin(), source.end(),  // start and end of source 
                    dest.begin(),                  // start of destination 
                    (int(*)(int const&)) addValue<int,5>);  // operation 
    

    但是我们要注意,非类型模板参数也有自己的局限,通常来说他们只能是常整数,包括枚举,或者指向外部链接的指针。如果我们用浮点数或者class-type objects作为非类型模板参数是错误的:

    template <double VAT>        // ERROR: floating-point values are not 
    double process (double v)    //        allowed as template parameters 
    { 
        return v * VAT; 
    } 
    
    template <std::string name>  // ERROR: class-type objects are not 
    class MyClass {              //        allowed as template parameters 
      … 
    }; 
    

    由于字串字面常熟是一种采用内部链接的物件,也就是说不通模组中的两个同值的字串字面常数其实是两个不同的东西,所以他们也不能用来作为模板参数:

    template <char const* name> 
    class MyClass { 
      … 
    }; 
    
    MyClass<"hello"> x;   // ERROR: string literal "hello" not allowed 
    

    此外全局指针也是不行的:

    template <char const* name> 
    class MyClass { 
      … 
    }; 
    
    char const* s = "hello"; 
    
    MyClass<s> x;         // ERROR: s is pointer to object with internal linkage 
    

    但是下面的例子是可以的:

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

    在这个例子中,s是一个外部连接的部件。

  • 相关阅读:
    css 响应式布局
    【nodejs】async
    vue移动appUI框架搭建-选取mintUI
    浅谈开发流程_敏捷开发流程_迭代流程的理解
    一篇业务需求上的数据处理问题--后台API只返回四个字段ABCD,现在数据量较大有20万条,一列上要展示ABCDABCDABCD这么些字段
    vue列表鼠标滚动翻页(数据量较大,几千万条数据,因此要滚动翻页,为了性能良好,鼠标滚动时发送请求页码page++),网上找不到自己写了一个,
    app移动端 rem和px的换算
    vue搜索关键字字体高亮, map映射新数组,replace替换,font字体样式
    vue文字截取方法 :title | filterFun方法过滤
    什么是正则表达式?
  • 原文地址:https://www.cnblogs.com/rollenholt/p/2384762.html
Copyright © 2011-2022 走看看