Allocator rebind

rebind的本质应该这么说:给定了类型T的分配器Allocator=allocator <T>,现在想根据相同的策略得到另外一个类型U的分配器allocator <U>,那么allocator <U> = allocator <T>::Rebind <U>::other.
之所以要提供rebind界面,是因为容器只知道模板参数名Allocator,而不是其具体实现,容器只知道这样三个事情:
1、Alocator是T的分配器,但其内部实现策略是什么容器并不关心(可能是std::allocator <T>,也可能是myallocator <T>)。换句话说,容器并不知道allocator模板名。
2、类型T和类型U在逻辑上是相关的,比如在链表中,数据类型T和结点类型Node <T>是有联系的。
3、容器希望按照和T一样的策略(具体的说就是相同的allocator模板名)来分配U类型的对象。
这时rebind的作用就体现出来了,标准中规定
对一个allocator <T>,和一个类型U,必须有allotor <T>::rebind <U>::other=allocator <U>,这样,
容器就可以得到U的分配器,
也就是说,rebind的本质应该是:,
对allotor <T>::rebind <U>,T和U的分配器必须是同一个模板名。这个模板可以是std::allocator,也可以是用户自定义的分配器模板 Myallocator,自然,为了使自己的分配器可以作为容器的模板参数,Myallocator中也必须定义rebind成员,且其实现必为
template <typename U>
rebind{
typedef Myallocator <U> other;
};
因此,同族的分配器指的是具有相同模板名的一组分配器。
如std::allcoator <T>和std::allcoator <U>是同族的,你可以把std::allcoator <T>::rebind <U>::other看成std::allcoator <U>。
Myallocator <T>和Myallocator <U>是同族的,你可以把Myallcoator <T>::rebind <U>::other看成Myallcoator <U>。
但allcoator <T>和Myallocator <U>就不是同族的
-----------------------BY http://topic.csdn.net/u/20080226/04/d3187cbf-c72e-4f29-b6f0-ed05e1f65f95.html

我们这个简单的array类不需要使用重绑定或转换,但这只是因为Array<T, Allocator>绝不产生T类型以外的对象。当你定义更复杂的数据结构时,其它类型就出现了。比如,考虑一下value_type是T的链表类 list。链表通常是由节点组成的,每个节点含有一个T类型的对象和一个指向下个节点的指针。于是,作为最初的尝试,我们可能定义链表的节点为:
    template <class T>
     struct List_node
     {
       T val;
       List_node* next;
     };
把一个新的值加入list的过程看起来可能是这样的:
l 使用一个value_type是List_node<T>的allocator,为一个新节点分配内存。 l 使用一个value_type是T的allocator,在节点的val位置上构建新的元素。 l 将这个节点连接到适当的位置。
这个过程需要处理两个不同的allocator,其中一个是通过对另一个的重绑定而获得的。它对几乎所有程序都工作得很好,即使是将allocator用于相当复杂的目的的程序。它所不能完成的是向allocator提供一些不寻常的指针类型。它明显依赖于能使用List_node<T> *类型的普通指针。
如果你极端野心勃勃,想将其它可能的指针类型传给allocator,一切都突然变得复杂多了--从一个节点指向另一个节点的指针不再是 List_node<T> *或void *了,但它必须是能够从allocator获取的某个类型。直接实现是不太可能的:用一个不完全的类型实例化allocator是非法的,因此,除非 List_node已经被完整定义,否则无法谈论指向List_node的指针。我们需要一个精巧的申明顺序。
    template <class T, class Pointer>
     struct List_node
     {
       T val;
       Pointer next;
     };
    template <class T, class Alloc>
     class List : private Alloc
     {
    private:
      typedef typename Alloc::template rebind<void>::other 
               Void_alloc;
      typedef typename Void_alloc::pointer Voidptr;
      typedef typename List_node<T, Voidptr> Node;
      typedef typename Alloc::template rebind<Node>::other
               Node_alloc;
      typedef typename Node_alloc::pointer Nodeptr;
      typedef typename Alloc::template rebind<Voidptr>::other
               Voidptr_alloc;
       Nodeptr new_node(const T& x, Nodeptr next) {
         Alloc a = get_allocator();
         Nodeptr p = Node_alloc(a).allocate(1);
        try {
           a.construct(p->val, x);
         }
        catch(...) {
           Node_alloc(a).deallocate(p, 1);
          throw;
         }
         Voidptr_alloc(a).construct(p->next, Voidptr(next));
        return p;
       }
      ...
     };
---------------------------BY http:
//www.stlchina.org/twiki/bin/view.pl/Main/STLWhatAllocator
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值