• 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是一个外部连接的部件。

  • 相关阅读:
    常见总结
    手机号中间四位替换为****
    写给30岁之前的我
    顺序栈ADT简单的实现
    快速排序
    关于存储类的例子总结
    非有序的静态查找表的查找某个元素的算法
    有序的静态查找表的折半(二分)查找算法
    【项目】项目125
    【项目】项目132
  • 原文地址:https://www.cnblogs.com/rollenholt/p/2384762.html
Copyright © 2020-2023  润新知