C++的模板(三):向模板传递模板

类模板是一种不完全的类型。它需要绑定参数,才能转化成实际的类型。这个过程叫做实例化。模板的参数必须是常数,或者类型。那么如果需要向模板传递模板该怎么办呢?

STL采用了rebind的办法。这是摘自STL allocator内存分配器的代码:

  template<typename _Tp>
    class new_allocator
    {
    public:
      typedef size_t     size_type;
      typedef ptrdiff_t  difference_type;
      typedef _Tp*       pointer;
      typedef const _Tp* const_pointer;
      typedef _Tp&       reference;
      typedef const _Tp& const_reference;
      typedef _Tp        value_type;

      template<typename _Tp1>
        struct rebind
        { typedef new_allocator<_Tp1> other; };

      new_allocator() throw() { }

      new_allocator(const new_allocator&) throw() { }

      template<typename _Tp1>
        new_allocator(const new_allocator<_Tp1>&) throw() { }

      ~new_allocator() throw() { }

      pointer
      address(reference __x) const { return &__x; }

      const_pointer
      address(const_reference __x) const { return &__x; }

      // NB: __n is permitted to be 0.  The C++ standard says nothing
      // about what the return value is when __n == 0.
      pointer
      allocate(size_type __n, const void* = 0)
      { return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp))); }

      // __p is not permitted to be a null pointer.
      void
      deallocate(pointer __p, size_type)
      { ::operator delete(__p); }

      size_type
      max_size() const throw()
      { return size_t(-1) / sizeof(_Tp); }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 402. wrong new expression in [some_] allocator::construct
      void
      construct(pointer __p, const _Tp& __val)
      { ::new(__p) _Tp(__val); }

      void
      destroy(pointer __p) { __p->~_Tp(); }
    };

new_allocator实例化了之后,它通过调用new_allocator::rebind::other又还原了这块代码的模板特性。在STL红黑树实现中,对传入数据类型,添加指针之后,用rebind::other来分配node内存。这里的allocator模板和rebind::other实际是一回事。

那么,可不可以在template 声明中直接传模板呢?比如代码这样写:
template < class T, template < class U > class allocator>

调试发现,这样写gcc是能够接受的。

#include <stdio.h>

#include <ext/new_allocator.h>

template <class T, template<class U>class Alloc=__gnu_cxx::new_allocator>
struct list {
        T  t;
        list *next;

        void insert(const T &t);
};

template <class T, template<class U>class Alloc>
void list<T,Alloc>:: insert(const T& t)
{
        list *node;
        Alloc<list> al;
        Alloc<T> at;
        node = al.allocate(1);
        at.construct(&node->t, t);
        node->next=next;
        next = node;
}

int main()
{
        list<int> l;
        l.t=0;
        l.next=0;
        l.insert(1);
        l.insert(2);
        l.insert(3);
        l.insert(4);
        l.insert(5);
        list<int> *p;
        p = &l;
        while(p) {
                printf("%d->", p->t);
                p= p->next;
        }
        printf("END\n");
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值