[STL] allocator 中 关于allocator::difference_type 和 allocator::rebind

czlc 2008-02-26 04:23:37
RT.

这两个定义有什么用,具体用于什么地方,请举例,谢谢。
...全文
993 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
joyjjjz 2010-06-28
  • 打赏
  • 举报
回复
mark
Allan_Draggon 2010-05-24
  • 打赏
  • 举报
回复
楼上说的有道理,容小弟再多解释一下:
Alocator 是内存分配器,STL在这个层面上进行开放是为了让用户/程序员有权选择不同的内存分配器。举例来说,Allocator_A和Allocator_B在内存分配方式上可能是不一样的,也就是说Allocator_A<int>和Allocator_B<int>所分配的内存很有可能是不一样的。

假如有一个容器类MyVector, 它用的是Allocator_A<int>内存分配器,这个容器类很有可能需要double类型的分配器,而且要求对int和double类型的内存分配策略是一样的,这是rebind的意义就体现出来了。

总之一句话,rebind实现了对不同类型使用同一种内存分配策略的要求。
laomai 2008-06-11
  • 打赏
  • 举报
回复
今天又仔细的看了一下,发现自己的回复还是有问题。
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>就不是同族的,
laomai 2008-06-10
  • 打赏
  • 举报
回复
hehe ,最近也在研究这个问题,今天晚上在和朋友讨论的过程中突然想出了点眉目。于是在这里写一个,
allocator<T>::rebind<U>可以看成是一个查询器或者说转换器,它查询的内容是:对给定的分配器
allocator<T>如何得到和T相关的类型U的分配器类型?
用数学的式子可以写成f=f(T, U),函数值就是rebind<U>::other,
也就是说
对给定类型T,U1、U2是两个和T相关的类型,那么必有
allocator<U1>::rebind<T>::other == allocator<U2>::rebind<T>::other = allocator<T>,
但是allocator<T>::rebind<U1>::other一般不等于allocator<T>::rebind<U2>::other
这个就是rebind的本质。
请注意这里T、U1、U2出现的位置.反过来说,
如果allocator<U1>::rebind<T>::other == allocator<U2>::rebind<T>::other,
那么U1、U2就是(关于T)同族的分配器。


  • 打赏
  • 举报
回复
《STL源码剖析》 好书呀
taodm 2008-02-26
  • 打赏
  • 举报
回复
看《STL源码剖析》
visame 2008-02-26
  • 打赏
  • 举报
回复
MARK!感觉说得不够清楚。。。等待高手!
yuyunliuhen 2008-02-26
  • 打赏
  • 举报
回复
---MSDN---


allocator::difference_type
A signed integral type that can represent the difference between values of pointers to the type of object managed by the allocator.
The signed integer type describes an object that can represent the difference between the addresses of any two elements in a sequence that an object of template class allocator can allocate.

// allocator_diff_type.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
#include <vector>

using namespace std;

int main( )
{
vector <int> v1;
vector <int>::iterator v1Iter;
vector <int>:: allocator_type v1Alloc;

int i;
for ( i = 0 ; i <= 7 ; i++ )
{
v1.push_back( i * 2 );
}

cout << "The original vector v1 is:\n ( " ;
for ( v1Iter = v1.begin( ) ; v1Iter != v1.end( ) ; v1Iter++ )
cout << *v1Iter << " ";
cout << ")." << endl;

allocator<int>::const_pointer v1PtrA, v1PtrB;
const int kA = 4, kB =12;
v1PtrA = v1Alloc.address( kA );
v1PtrB = v1Alloc.address( kB );
allocator<int>::difference_type v1diff = *v1PtrB - *v1PtrA;

cout << "Pointer v1PtrA addresses " << *v1PtrA << "." << endl;
cout << "Pointer v1PtrB addresses " << *v1PtrB << "." << endl;
cout << "The difference between the integer's addresses is: "
<< v1diff << "." << endl;
}




allocator::rebind

A structure that enables an allocator for objects of one type to allocate storage for objects of another type



// allocator_rebind.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

typedef vector<int>::allocator_type IntAlloc;
int main( )
{
IntAlloc v1Iter;
vector<int> v1;

IntAlloc::rebind<char>::other::pointer pszC =
IntAlloc::rebind<char>::other(v1.get_allocator()).allocate(1, (void *)0);

int * pInt = v1Iter.allocate(10);
}

CQZE 2008-02-26
  • 打赏
  • 举报
回复
difference_type offset = ptr1 - ptr2;
ptr1 和 ptr2是同一个内存分配器分配出来的buffer首地址。用来表示偏移的类型,有符号的。

allocator::rebind
一个典型的template typedef,作用就是:
先看vector的分配器是allocator<T>,你要多少T就给你他就给你多少个T的对象。和new出来的一样。
再看看list的分配器,同样也是allocator<T>,但是了解 链表 这个数据结构的都知道一个node应该是
template<T>
struct node
{
T data;
node* prev;
node* next;
};
所以allocator<T>就无法分配出一个node对象,而仅仅是T对象,象vector的那样。
尽管list的allocator<T>和vector的allocator<T>是一样,但是list还是有其他的办法,它在内部由allocator<T>来获取适合它自己的分配器。
allocator<T>::rebind<node<T> >::other,这个other就是allocator<node<T> >
list就用这个other来分配内存了。
czlc 2008-02-26
  • 打赏
  • 举报
回复
看了,就是看在这里就停了。

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧