zoukankan      html  css  js  c++  java
  • c++ template归纳学习5

    双重模板参数:

    我们还是以前几篇中的Stack为例子i:代码如下:

    template <typename T, 
              template <typename ELEM> class CONT = std::deque > 
    class Stack { 
      private: 
        CONT<T> elems;         // elements 
    
      public: 
        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 elems.empty(); 
        } 
    }; 
    在这段代码中,我们的第二个模板参数修改为:template <typename ELEM> class CONT

    和往常一样,你可以使用class替代typename,但是CONT必须是class。

    template <typename T, 
              template <class ELEM> class CONT = std::deque>  // OK 
    class Stack { 
      … 
    }; 
    but the following is not:
    
    template <typename T, 
              template <typename ELEM> typename CONT = std::deque> 
    class Stack {                                             // ERROR 
      … 
    };
    

    由于上面例子中的ELEM实际中没有用到,其实是可以省略的。

    我们实现一个成员函数看看:

    template <typename T, template <typename> class CONT> 
    void Stack<T,CONT>::push (T const& elem) 
    { 
        elems.push_back(elem);    // append copy of passed elem 
    } 
    

    但是如果试图使用上面的stack,编译器会说deque不符合CONT的要求,问题在于,std中的deque要求不只是一个参数,第二个参数是一个配置器,他虽然有预设值,但是当它被用来匹配CONT参数的时候,预设值被编译器忽略了。

    对于这个问题,我们可以修改,使得CONT参数要求一个带两个参数的容器。

    template <typename T, 
              template <typename ELEM, 
                        typename ALLOC = std::allocator<ELEM> > 
                        class CONT = std::deque> 
    class Stack { 
      private: 
        CONT<T> elems;         // elements 
        … 
    }; 
    
    最终版本如下:

    // basics/stack8.hpp 
    
    #ifndef STACK_HPP 
    #define STACK_HPP 
    
    #include <deque> 
    #include <stdexcept> 
    #include <allocator> 
    
    template <typename T, 
              template <typename ELEM, 
                        typename = std::allocator<ELEM> > 
                        class CONT = std::deque> 
    class Stack { 
      private: 
        CONT<T> elems;        // elements 
    
      public: 
        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 elems.empty(); 
        } 
    
        // assign stack of elements of type T2 
        template<typename T2, 
                 template<typename ELEM2, 
                          typename = std::allocator<ELEM2> 
                          >class CONT2> 
        Stack<T,CONT>& operator= (Stack<T2,CONT2> const&); 
    }; 
    
    template <typename T, template <typename,typename> class CONT> 
    void Stack<T,CONT>::push (T const& elem) 
    { 
        elems.push_back(elem);    // append copy of passed elem 
    } 
    
    template<typename T, template <typename,typename> class CONT> 
    void Stack<T,CONT>::pop () 
    { 
        if (elems.empty()) { 
            throw std::out_of_range("Stack<>::pop(): empty stack"); 
        } 
        elems.pop_back();         // remove last element 
    } 
    
    template <typename T, template <typename,typename> class CONT> 
    T Stack<T,CONT>::top () const 
    { 
        if (elems.empty()) { 
            throw std::out_of_range("Stack<>::top(): empty stack"); 
        } 
        return elems.back();      // return copy of last element 
    } 
    template <typename T, template <typename,typename> class CONT> 
     template <typename T2, template <typename,typename> class CONT2> 
    Stack<T,CONT>& 
    Stack<T,CONT>::operator= (Stack<T2,CONT2> const& op2) 
    { 
        if ((void*)this == (void*)&op2) {    // assignment to itself? 
            return *this; 
        } 
    
        Stack<T2> tmp(op2);              // create a copy of the assigned stack 
    
        elems.clear();                   // remove existing elements 
        while (!tmp.empty()) {           // copy all elements 
            elems.push_front(tmp.top()); 
            tmp.pop(); 
        } 
        return *this; 
    } 
    
    #endif // STACK_HPP 
    
    测试如下:

    // basics/stack8test.cpp 
    
    #include <iostream> 
    #include <string> 
    #include <cstdlib> 
    #include <vector> 
    #include "stack8.hpp" 
    
    int main() 
    { 
        try { 
            Stack<int> intStack;        // stack of ints 
            Stack<float> floatStack;    // stack of floats 
    
            // manipulate int stack 
            intStack.push(42); 
            intStack.push(7); 
    
            // manipulate float stack 
            floatStack.push(7.7); 
    
            // assign stacks of different type 
            floatStack = intStack; 
    
            // print float stack 
            std::cout << floatStack.top() << std::endl; 
            floatStack.pop(); 
            std::cout << floatStack.top() << std::endl; 
            floatStack.pop(); 
            std::cout << floatStack.top() << std::endl; 
            floatStack.pop(); 
        } 
        catch (std::exception const& ex) { 
            std::cerr << "Exception: " << ex.what() << std::endl; 
        } 
    
        // stack for ints using a vector as an internal container 
        Stack<int,std::vector> vStack; 
        … 
        vStack.push(42); 
        vStack.push(7); 
        std::cout << vStack.top() << std::endl; 
        vStack.pop(); 
    } 
    
    程序的输出为:

    7 42 Exception: Stack<>::top(): empty stack 7

  • 相关阅读:
    python 模拟浏览器
    转:如何评价架构的优劣
    转:DotNET企业架构应用实践架构师成长之路如何成为优秀架构师
    转:大规模网站架构实战之体系结构(一)
    转:Twitter的设计原则
    转:关于大型asp.net应用系统的架构—如何做到高性能高可伸缩性
    转:我眼中的Visual Studio 2010架构工具
    转:解剖Twitter
    转:Discuz!NT前台模型架构(MVC)
    转: "HTTP 错误 401.1 未经授权:访问由于凭据无效被拒绝"的另类解决方案
  • 原文地址:https://www.cnblogs.com/rollenholt/p/2384921.html
Copyright © 2011-2022 走看看