zoukankan      html  css  js  c++  java
  • 模板系列(一) 模板的模板参数

    前面我们写过类似的Stack:

    template <typename T, typename Alloc = std::vector<T> >
    class Stack
    {
    public:
          void push(const T &);
          void pop();
          T top() const;
          bool empty() const;
    private:
          Alloc _cont;
    };

    那么我们使用的时候需要这样:

    Stack<string, list<string> > st;

    我们看到,string这个类型参数出现了两次,那么可不可以消除呢?

    显然我们的目的是只指定容器的类型,而不包括元素的类型,这就需要借助模板的模板参数,来帮助我们写出一下代码:

    Stack<string, list> st;

    这里我们需要定义模板参数的第二项为模板:

    template <typename T,
              template <typename ELEM>
              class Alloc = std::vector>
    class Stack;

    我们写出一份完整的实现:

     1 template <typename T,
     2           template <typename ELEM>
     3           class Alloc = std::vector>
     4 class Stack
     5 {
     6 public:
     7     void push(const T &s);
     8     void pop();
     9     T top() const
    10     { return _cont.back(); }
    11 
    12     bool empty() const
    13     { return _cont.empty(); }
    14 private:
    15     Alloc<T> _cont;
    16 };
    17 
    18 template <typename T, template <typename> class Alloc>
    19 void Stack<T, Alloc>::push(const T &s)
    20 {
    21     _cont.push_back(s);
    22 }
    23 
    24 template <typename T, template <typename> class Alloc>
    25 void Stack<T, Alloc>::pop()
    26 {
    27     _cont.pop_back();
    28 }

    然而该段代码仍然会编译错误,这是因为无论是vector还是list都有两个模板参数,于是无法与Alloc这个参数匹配。
    我们将模板修改为:

    template <typename T,
              template <typename ELEM, typename Alloc = std::allocator<ELEM> >
              class Container = std::vector>
    class Stack;


    完整的实现为:

     1 template <typename T,
     2           template <typename ELEM, typename Alloc = std::allocator<ELEM> >
     3           class Container = std::vector>
     4 class Stack
     5 {
     6 public:
     7     void push(const T &s);
     8     void pop();
     9     T top() const
    10     { return _cont.back(); }
    11 
    12     bool empty() const
    13     { return _cont.empty(); }
    14 private:
    15     Container<T> _cont;
    16 };
    17 
    18 template <typename T, template <typename, typename> class Container>
    19 void Stack<T, Alloc>::push(const T &s)
    20 {
    21     _cont.push_back(s);
    22 }
    23 
    24 template <typename T, template <typename, typename> class Container>
    25 void Stack<T, Alloc>::pop()
    26 {
    27     _cont.pop_back();
    28 }


    测试代码为:

    Stack<string, list> st;
    st.push("foo");
    st.pop();
  • 相关阅读:
    vi编辑器
    在shell脚本中使用函数
    在shell脚本中进行条件控制以及使用循环
    shell指令expr和test指令
    利用ps指令查看某个程序的进程状态
    shell变量的使用
    创建和运行shell脚本程序
    关于强制类型转换(c语言)
    elastic 常用查询操作
    elastic 集群安装
  • 原文地址:https://www.cnblogs.com/gjn135120/p/4008773.html
Copyright © 2011-2022 走看看