赫尔辛基到罗凡涅米:C++箴言:为类型信息使用特征类-C/C++-华夏名网资讯中心 虚拟主机,域名注册,双线虚...

来源:百度文库 编辑:九乡新闻网 时间:2024/07/14 04:34:06
  • C++箴言:为类型信息使用特征类
  • 来源:作者: 发布时间:2007-04-04 08:00:00
  • STL 主要是由 containers(容器),iterators(迭代器)和 algorithms(算法)的 templates(模板)构成的,不过也有几个 utility templates(实用模板)。其中一个被称为 advance。advance 将一个指定的 iterator(迭代器)移动一个指定的距离:

    template // 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
    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(内建类型)。

      traits 对 built-in types(内建类型)必须有效的事实意味着将信息嵌入到类型内部是不能的,因为没有办法将信息嵌入指针内部。那么,一个类型的 traits 信息,必须在类型外部。标准的方法是将他放到 template(模板)及这个 template(模板)的一个或更多的 specializations(特化)中。对于 iterators(迭代器),标准库中 template(模板)被称为 iterator_traits:

    template // template for information about
    struct iterator_traits; // iterator types

      就像你能看到的,iterator_traits 是个 struct(结构体)。根据惯例,traits 总是被实现为 struct(结构体)。另一个惯例就是用来实现 traits 的 structs(结构体)以 traits classes(这可不是我捏造的)闻名。

      iterator_traits 的工作方法是对于每一个 IterT 类型,在 struct(结构体)iterator_traits 中声明一个名为 iterator_category 的 typedef。这个 typedef 被看成是 IterT 的 iterator category(迭代器种类)。
  • C++箴言:为类型信息使用特征类-C/C++-华夏名网资讯中心 虚拟主机,域名注册,双线虚... UNIX下ORACLE数据库的创建-PHP编程-华夏名网资讯中心 虚拟主机,域名注册,双线... Linux USB驱动框架分析-Linux -华夏名网资讯中心 虚拟主机,域名注册,双线虚拟主机,服务器租赁,为7万用户提供服务 黑客常用的远程控制命令-网络安全 -华夏名网资讯中心 虚拟主机,域名注册,双线虚拟主机,服... 从信息技术的演变看业务和技术融合-行业资讯-华夏名网资讯中心 虚拟主机,域名注册,双线虚拟... 网络存储:SAN和NAS一起构建数字档案馆-存储备份-华夏名网资讯中心 虚拟主机,域名注册... Word文档转为PPT演示文档的两种方法-冲浪宝典-华夏名网资讯中心 虚拟主机,域名注册,... 为自己的asp网站系统构建一套标记语言_asp技巧-ASP编程-华夏名网资讯中心 虚拟主机... Linux环境进程间通信(五): 共享内存(上)-Linux -华夏名网资讯中心 虚拟主机... C语言之内存使用 详解C语言中的VOID类型 定义结构类型——C语言 c语言中的自动类型转换 茶艺基本知识 C c C C interview questions : 如何混合使用C和C (上) C/C 数组名与指针区别深入探索 windows下使用xmanager登录linux远程桌面-Linux -华夏名网资讯中心... C#_Stopwatch 类 const用法详解 - C/C / C 语言 中国十大域名注册商排行榜 中国域名注册商排名 中国十大域名注册虚拟主机服务商排行榜 ... ortp库使用入门-C/C++ Linux 内核使用的 GNU C 扩展 工业-C