Item 47 用trait类提供类型信息

STL主要由容器、迭代器和算法这三类模板组成。也包含一些工具模板,比如:

 

在实现上,只有支持随机访问的迭代器才能用+=,功能稍弱的只能用++和--重复执行。

迭代器分5类:
1> Input Iterator  只能前行,一次一步,指谁读谁,而且只能读一次。代表:istream_iterator
2> Output Iterator 与上同。用于写操作。代表:ostream_iterator

这两类功能最弱,只能用于那些单行的算法(one-pass)。

3> Forward Iterator       前行,一步,可读写多次。所以可用于多行算法(multi-pass)。代表:slist
4> Bidirectional Iterator 前后双行,一步,可读写多次。代表:list、set、multiset、map、multimap
5> Random Access Iterator 前后双行,N步,可读写多次。代表:vector、deque、string

使用上面的迭代器来实现advance,大致是下面的样子:

 

我们如何才能在编译时知道一个迭代器的类型呢?

C++的世界使用trait类来实现这个功能。下面是迭代器的trait类模板:

 

● 先为这五类迭代器定义五个标签,每个标签代表一种迭代器。注意每个标签都是空的,它们只有名字而已。

 

● 用这些标签给每个容器的迭代器定义一个iterator_category类型。这样,每个迭代器就都有了个叫做 iterator_category 的内置类型。

 

 

● 然后让trait类重复一遍该定义。这样迭代器的trait类就能识别所有迭代器的category信息了。

 

● 为了让C++的指针也支持trait类,需要再重复一遍该定义

 

● 于是,advance可以根据迭代器的种类做出判断了:

 

 

不过,如此实现的advance有两个问题:其中之一将在Item 48里讨论。先介绍另一个:
iterator_traits<IterT>::iterator_category其实在编译时就可以决定了。if语句是在运行时对其进行的判断。
我们编译时就可以解决的问题,不应该留到后面。

对于advance在编译时对类型的判断,我们可以用“重载”来实现。

 

 

● STL中广泛使用了trait类,如char_traits和numeric_limits。TR1中的:
is_fundamental<T>
is_array<T>
is_base_of<T1, T2>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值