分享
 
 
 

[翻译] Effective C++, 3rd Edition, Item 47: 为类型信息使用 traits classes(特征类)(上)

王朝c/c++·作者佚名  2006-02-14
窄屏简体版  字體: |||超大  

Item 47: 为类型信息使用 traits classes(特征类)

作者:Scott Meyers

译者:fatalerror99 (iTePub's Nirvana)

发布:http://blog.csdn.net/fatalerror99/

STL 主要是由 containers(容器),iterators(迭代器)和 algorithms(算法)的 templates(模板)构成的,但是也有几个 utility templates(实用模板)。其中一个被称为 advance。advance 将一个指定的 iterator(迭代器)移动一个指定的距离:

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(哈希容器)(参见 Item 54)的 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 关系(参见 Item 32):所有的 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(内建类型)。

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

template<typename IterT> // template for information about

struct iterator_traits; // iterator types

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

iterator_traits 的工作方法是对于每一个 IterT 类型,在 struct(结构体)iterator_traits<IterT> 中声明一个名为 iterator_category 的 typedef。这个 typedef 被看成是 IterT 的 iterator category(迭代器种类)。

(本篇未完,点击此处,接下篇)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有