关于几个SGI STL的问题?

hyqryq 2003-08-04 12:35:00
最近看侯捷的, 有一些问题,
1.有如下代码, 
static void (*set_malloc_handler(void(*f()))() {
....
}
<<STL源码剖析>>, P57.
谁能给分析一下?

2.在 defalloc.h 中 init_page_size 与 max_size 函数有什么用处?

<<STL源码剖析>>, P49.

3.在list的迭代器中, 使用了三个模版参数,

template <class T, class T&, class Ptr>
struct __list_iterator {
typedef __list_iterator <T, T& T*> iterator;
typedef __list_iterator <T, Ref, Ptr> self;
为何要使用三个模版参数?我认为一个就够了。 而且为何iterator和self的定义不同? <<STL源码剖析>>, P130




...全文
10 点赞 收藏 23
写回复
23 条回复
hyqryq 2003年08月06日

多谢两位的回答, 两位不要吵了。 我想没有必要去抠字眼把。

两位上面说得都有道理。
我想了想,主要理由就是解决由 const 所引起的类型不一致.

如果在模版参数中使用智能指针还是有些问题。

template <class T, class Ref, class Ptr> // 这里 Ref似乎不能使用智能指针。
struct __list_iterator {
typedef __list_iterator <T, T&, T*>; // 这里杜绝了使用智能指针的可能。
...
}

个人认为<<STL源码剖析>>中,丢掉的那一行还是颇为重要的, 影响理解。

欢迎讨论。
回复 点赞
yjh1982 2003年08月06日
我也看了一下@_@
list中有
typedef _List_iterator<_Tp,_Tp&,_Tp*> iterator;
typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
说明_List_iterator 应该有这么多模板参数;

list中这些iterator 与const_iterator有特别理由分别采用吗?
有两点;
一的理由是:list对象的find,begin等函数返回iterator; const list则是const_iterator;两种迭代器不能互相比较,赋值,这样可以提醒用户
二.typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator中const_iterator 的实现不能改动数据,在_List_iterator 中
reference
operator*() const
{ return ((_Node*) _M_node)->_M_data; }

pointer
operator->() const
{ return &(operator*()); }
而reference 对应const T& pointer对应const T*

回复 点赞
flewsky 2003年08月06日
come on!
回复 点赞
magicblue 2003年08月06日
无语!都说了些什么乱七八糟的,我怀疑你有没有搞清楚别人再问什么啊??
你的言论我实在懒得回,因为你根本理解不了似的,淅沥哇啦说一堆不相干的,佩服!佩服!

>> 楼主问到:
>> 不过这里我还是有疑问,为何要区分 self 与 pointer ?

请你搞清楚,别人问的是self和iterator,不是pointer

>> self是_List_iterator<_Tp, const _Tp&, const_Tp*>
>>
>> 这一点您说对了.可没说明问题呀.我想搂主怕是不满意的.


我是这么说的吗??你看仔细点。

>> "operator++的返回类型就是iterator&."我想未必吧.就是不定义self
>> operator++也应返回List_iterator<T, Ref, Ptr>& 能返回List_iterator<T, T&, T*>
>> 吗?
>> 您是明白人,怕是不行吧.


严重的理解错误,搂主问“为何要定义self?”如果不定义self(那么就没有ref,ptr),所以只有返回iterator

从你的看法可以推出ptr模板参数可以是iterator!how ridiculous!

最没风度的就是你这种,一来就摆出一付旷世高手的样子,你以为你是谁啊?水平好点也到罢了,kao,浪费时间
回复 点赞
yjh1982 2003年08月06日
两位都忍忍吧,C++无高手!
回复 点赞
magicblue 2003年08月06日
sign.
any problem?
回复 点赞
solotony 2003年08月06日
还真是吓了我一跳"三脚猫代码是可以定义,在stl中不行。"
"你能做到不误人子弟就够了",这是我老师来了呀

我不过驳了你一句"照楼上的说法list岂不乱套",看看你都说了些什么?
本来就是讨论,有错,您指出来.我没话说,您有错,我也指出来,大家进步.
难到非要骂架不成?

您问了:
self& operator++()的返回值又如何与iterator<T,T&,T*>匹配???
我也说了如何匹配.

您看仔细了,我说的道理和你后来说的有差没差.
"而不是一个特化了的iterator",想必你是看到这就没细想.
我为什么要举一个特化的例子呢?
不过是因为特化的情况下self 和iterator根本是一样的.

你后面说
"operator++的返回类型就是iterator&."我想未必吧.就是不定义self
operator++也应返回List_iterator<T, Ref, Ptr>& 能返回List_iterator<T, T&, T*>吗?
您是明白人,怕是不行吧.

假如我们对一个const_iterator操作,它的类型是什么?
怕你再说我不学无术,我还真去查了一下STL源码
结果是这个:
typedef _List_iterator<_Tp,_Tp&,_Tp*> iterator;
typedef _List_iterator<_Tp, const _Tp&,const _Tp*> const_iterator;

那么在_List_iterator中
iterator 就是_List_iterator<_Tp, _Tp&, _Tp*>
const iterator 就是_List_iterator<_Tp, const _Tp&, const_Tp*>
self是_List_iterator<_Tp, const _Tp&, const_Tp*>

这一点您说对了.可没说明问题呀.我想搂主怕是不满意的.

楼主问到:
不过这里我还是有疑问,为何要区分 self 与 pointer ?
为何有些函数返回 pointer, 例如 operator->(),
有些函数返回 self, 例如 opeartor++(), operator--()?

这只能从返回引用和指针的角度讲.

楼主又问到:
为何有这样的定义
typedef __list_iterator <T, T& T*> iterator; (这是iterator,不是pointer)
typedef __list_iterator <T, Ref, Ptr> self;
为什么这Self的定义是这样的,我前面已经说了.Ref可能不等于T&
而为两个定义不一样,准确的说这一点我也吃不准,因为在整个list的实现中
iterator只在挎贝构造中出现了一次.

_List_iterator(const iterator& __x) : _List_iterator_base(__x._M_node) {}

通过它可以把iterator类型变为self类型.这大概就是iterator定义的由来.
至于const_iterator, 我想<<STL源码剖析>>中略过它,也是有理由的,因为
根本就没有用到过它.

说到这里,我想请楼主注意:
你后来又问的两个问题,实际上并不相关.self 与 pointer,self与iterator之间
的关系并不一样.

至于"而且我非常感兴趣的是你所说的“类型LPT是具有T*指针行为的类型”,你写一个例子出来?"
我想还是免了罢,我那三脚猫的功夫就不丢人了.所有的Iterator都是良好的具有T*指针行为的类.

人,还是有点风度的好.
回复 点赞
hyqryq 2003年08月05日
楼上的请给解释一下。
回复 点赞
magicblue 2003年08月05日
对于搂主的问题我还是坚持我的看法。首先STL是一个非常严谨,规范的库。
template <class T, class Ref, class Ptr>
struct __list_iterator {
typedef __list_iterator <T, T& T*> iterator;
typedef __list_iterator< T, const T &, const T * > const_iterator;//我查看了stlport原码,这一行被 STL源码剖析 漏掉了。这也是问题所在
typedef __list_iterator <T, Ref, Ptr> self;
......
self& operator++(){
......
return *this;
}
};
注意,operator++ 是__list_iterator 的成员,那么self的类型就应该是__list_iterator 自身,即__list_iterator <T, Ref, Ptr>,即self。而不是一个特化了的iterator。这是理论上的回答。另一方面,我们不要self,那么operator++的返回类型就是iterator&。现在我对一个const_iterator实行++操作,这个时候返回的*this便与返回类型iterator&不匹配。一个是__list_iterator <T, T& T*>一个是typedef __list_iterator< T, const T &, const T * >,对于C++这样的强类型语言来说,这是一个错误。

我的回答搂主满意吗?

btw:
有些人只懂些皮毛,就会摆架子。还觉得别人不虚心。你能做到不误人子弟就够了,别打肿脸充胖子。我并不是不赞同“狂”,但是也先得掂掂自己的斤两。我不是针对solotony一个人说的,现在的社会有不少这种人
本来不想说这些,不过实在是有点气
回复 点赞
solotony 2003年08月05日
template <class T, class Ref, class Ptr>

这三个类型是可以完全不同的,请注意
对于类型T
T&是它的内置引用类型,却不是它的唯一引用类型
T*也不是唯一的指针类型.


回复 点赞
magicblue 2003年08月05日
solotony:

你的operator++写错了,这是基本常识;
stl中list::iterator是__list_iterator <T, Ref, Ptr>的typedef,你如何定义list::iterator<a,b,c>?你写的那几行三脚猫代码是可以定义,在stl中不行。
而且我非常感兴趣的是你所说的“类型LPT是具有T*指针行为的类型”,你写一个例子出来?
回复 点赞
hyqryq 2003年08月05日
返回引用还是指针这个问题我明白。

核心问题还是,为何 self 要这样定义? 明明一个参数就可以搞定的。
既然用三个模版参数, 那么 iterator 和 self 为何不一样?

typedef __list_iterator <T, T& T*> iterator;
typedef __list_iterator <T, Ref, Ptr> self;
回复 点赞
solotony 2003年08月05日
operator->()返回pointer的,是因为它的结果要用于做为成员引用的
而opeartor++()返回self是因为它的结果要用于左值或右值

这不是<要>区分,而是<必须>区分.
回复 点赞
hyqryq 2003年08月05日
to solotony(solotony):
Thanks for you answer.
不过这里我还是有疑问,为何要区分 self 与 pointer ?
为何有些函数返回 pointer, 例如 operator->(),
有些函数返回 self, 例如 opeartor++(), operator--()?
回复 点赞
solotony 2003年08月05日
magicblue(小飞侠)
不明白就要问,不过要虚心的问.


我来解释一下,举个例子来说.
指针的行为比引用简明一点,原理是一样的,下面我以指针为例.

类型T是原始类型,类型LPT是具有T*指针行为的类型.
即是如果有LPT p,*p返回一个T,&p返回一个T*, p->可以引用T的成员...指针的概念并没有说完

template <class T, class Ptr> //暂略去引用类型
struct I{
typedef I<T, Ptr> self;
typedef I<T, T*> pointer;

self& operator++(){
return this;
}
};
想必还有
template <class T> //暂略去引用类型
struct I<T, T*>{
typedef I<T, T*> self;
typedef I<T, T*> pointer;
self& operator++(){
return this;
}
};


I<T, LPT> a; //有何不可?
I<T, T*> b; //也是可以?

a++ //类型?

回复 点赞
magicblue 2003年08月05日
照楼上的说法list岂不乱套?再说你又如何自定义list::iterator的ref,ptr??
self& operator++()的返回值又如何与iterator<T,T&,T*>匹配???
absolute nonsense
回复 点赞
yjh1982 2003年08月05日
即:template <class T, class Ref, class Ptr>
Ref一般是T&但也可为一个行为象T&的类,
Ptr如是
回复 点赞
magicblue 2003年08月04日
楼上的错了
set_malloc_handler是一个指向函数的指针,它指向的函数的参数是形如void (*f)()的函数指针。

max()的作用是如果T的实例大于4096字节的话,init_page_size为1,而不是一个小数。
max_size可能是取得能在一定理想性能下处理的页大小。

应该是template <class T, class Ref, class Ptr>
正是因为iterator和self定义不同才会有Ref和Ptr,定义出self可能是因为规格的要求吧。其实用iterator也是可以的。这一点是我的想法
回复 点赞
hyqryq 2003年08月04日
to ckp(surge),

可以给解释一下吗? 这里取两个size_type中的大者是什么意思?
------------------------------------------------------
template <class T>
...
size_type init_page_size() {
return max(size_type(1), size_type(4096/sizeof(T));
}
...
-------------------------------------------------------
回复 点赞
ckp 2003年08月04日
defalloc.h 中 init_page_size 与 max_size 函数有什么用处?
init_page_size是取得定义的页尺寸,
max_size不清楚,
回复 点赞
发动态
发帖子
工具平台和程序库
创建于2007-09-28

8236

社区成员

2.7w+

社区内容

C/C++ 工具平台和程序库
社区公告
暂无公告