C 箴言:为类型信息使用特征类
2008-02-23 05:27:16来源:互联网 阅读 ()
template<typename IterT, typename DistT> // move iter d units void advance(IterT& iter, DistT d); // forward; if d < 0, // move iter backward |
在概念上,advance 仅仅是在做 iter = d,但是 advance 不能这样实现,因为只有 random access iterators(随机访问迭代器)支持 = operation。不够强力的 iterator(迭代器)类型不得不通过反复利用 或 -- d 次来实现 advance。
您不记得 STL iterator categories(迭代器种类)了吗?没问题,我们这就做一个简单回顾。对应于他们所支持的操作,共有五种 iterators(迭代器)。input iterators(输入迭代器)只能向前移动,每次只能移动一步,只能读他们指向的东西,而且只能读一次。他们以一个输入文档中的 read pointer(读指针)为原型;C 库中的 istream_iterators 就是这一种类的典型代表。output iterators(输出迭代器)和此类似,只但是用于输出:他们只能向前移动,每次只能移动一步,只能写他们指向的东西,而且只能写一次。他们以一个输出文档中的 write pointer(写指针)为原型;ostream_iterators 是这一种类的典型代表。这是两个最不强力的 iterator categories(迭代器种类)。因为 input(输入)和 output iterators(输出迭代器)只能向前移动而且只能读或写他们指向的地方最多一次,他们只适合 one-pass 运算。
一个更强力一些的 iterator category(迭代器种类)是 forward iterators(前向迭代器)。这种 iterators(迭代器)能做 input(输入)和 output iterators(输出迭代器)能够做到的每一件事情,再加上他们能够读或写他们指向的东西一次以上。这就使得他们可用于 multi-pass 运算。STL 没有提供 singly linked list(单向链表),但某些库提供了(通常被称为 slist),而这种 containers(容器)的 iterators(迭代器)就是 forward iterators(前向迭代器)。TR1 的 hashed containers(哈希容器)的 iterators(迭代器)也能够属于 forward category(前向迭代器)。
bidirectional iterators(双向迭代器)为 forward iterators(前向迭代器)加上了和向前相同的向后移动的能力。STL 的 list 的 iterators(迭代器)属于这一种类,set,multiset,map 和 multimap 的 iterators(迭代器)也相同。
最强力的 iterator category(迭代器种类)是 random access iterators(随机访问迭代器)。这种 iterators(迭代器)为 bidirectional iterators(双向迭代器)加上了 "iterator arithmetic"(“迭代器运算”)的能力,也就是说,在常量时间里向前或向后跳转一个任意的距离。这样的运算类似于指针运算,这并不会让人感到惊讶,因为 random access iterators(随机访问迭代器)就是以 built-in pointers(内建指针)为原型的,而 built-in pointers(内建指针)能够和 random access iterators(随机访问迭代器)有同样的行为。vector,deque 和 string 的 iterators(迭代器)是 random access iterators(随机访问迭代器)。
对于五种 iterator categories(迭代器种类)中的每一种,C 都有一个用于识别他的 "tag struct"(“标签结构体”)在标准库中:
struct input_iterator_tag {}; struct output_iterator_tag {}; struct forward_iterator_tag: public input_iterator_tag {}; struct bidirectional_iterator_tag: public forward_iterator_tag {}; struct random_access_iterator_tag: public bidirectional_iterator_tag {}; |
这些结构体之间的 inheritance relationships(继承关系)是正当的 is-a 关系:任何的 forward iterators(前向迭代器)也是 input iterators(输入迭代器),等等,这都是成立的。我们不久就会看到这个 inheritance(继承)的功用。
但是返回到 advance。对于不同的 iterator(迭代器)能力,实现 advance 的一个方法是使用反复增加或减少 iterator(迭代器)的循环的 lowest-common-denominator(最小共通特性)策略。然而,这个方法要花费 linear time(线性时间)。random access iterators(随机访问迭代器)支持 constant-time iterator arithmetic(常量时间迭代器运算),当他出现的时候我们最好能利用这种能力。
我们真正想做的就是大致像这样实现 advance:
template<typename IterT, typename DistT> void advance(IterT& iter, DistT d) { if (iter is a random access iterator) { iter = d; // use iterator arithmetic } // for random access iters else { if (d >= 0) { while (d--) iter; } // use iterative calls to else { while (d ) --iter; } // or -- for other } // iterator categories } |
这就需要能够确定 iter 是否是个 random access iterators(随机访问迭代器),依次下来,就需要知道他的类型,IterT,是否是个 random access iterators(随机访问迭代器)类型。换句话说,我们需要得到关于一个类型的某些信息。这就是 traits 让您做到的:他们允许您在编译过程中得到关于一个类型的信息。 traits 不是 C 中的一个关键字或预定义结构;他们是一项技术和 C 程式员遵守的惯例。建立这项技术的需要之一是他在 built-in types(内建类型)上必须和在 user-defined types(用户定义类型)上相同有效。例如,假如 advance 被一个指针(譬如一个 const char*)和一个 int 调用,advance 必须有效,但是这就意味着 traits 技术必须适用于像指针这样的 built-in types(内建类型)。
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇: C 对象布局及多态探索之菱形结构虚继承
下一篇: 验C 中接口和实现分离的技术
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash