本节条款的题目:请使用trait classes来表示类型信息

本节条款主要讲述的技术是怎样在编译期间实现对迭代器类型的推断,依据推断的类型进行最优处理。

我们先来看一下迭代器的种类:

1.input_iterator:仅仅读,仅仅能逐个前移

2.output_iterator:仅仅写,仅仅能逐个前移

3.forward_iterator:可读可写,仅仅能逐个前移

4.bidirectional_iterator:可读可写,支持逐个前移和后移

5.random_access_iterator:可读可写,支持随机訪问(随意步数移动)

假设一下,假设有一个函数用于对迭代器指定移动次数d,我们怎样实现这个函数,以达到最理想的状态。

我们肯定会处理迭代器是random access类型的情况和不是random access类型的情况。当时random access的时候,直接加减迭代器在常数时间内完毕,假设不是,仅仅能一步一步向前或向后移动。

例如以下代码:

template<typename Iter, typename DistT>
void advance(IteT& iter,DistT d)
{
if(iter is a random access iterator)
iter+=d;
else
{
if(d>=0)
while(d--) ++iter;
else
while(d++) --iter;
}
}

但是,我们怎么才干做到“iter is a random access iterator”在编译期间的实现?

实现这个功能。须要下面几步,而且相对繁杂的几步。

首先为每一种迭代器设置struct标签,每一个struct都是空的结构体,例如以下代码:

struct input_iterator_tag{};

struct output_iterator_tag{};

struct forward_iterator_tag: public input_iterator_tag{};

struct bidirectional_iterator: public forward_iterator_tag{};

struct random_access_iterator: public bidirectional_iterator_tag{};

接着。我们就要引入traits,traits是一种技术,我们通过程序来看一下这是什么技术。有什么用。

我们来看一下关于各种容器的定义:

template class <T>
class vector
{
public:
class iterator
{
public:
typedef random_access_iterator iterator_category;

}

} template class <T>
class list
{
public:
class iterator
{
public:
typedef bidirectional_iterator iterator_category;

}

}

从上面代码能够看出,每一个容器中都有一个iterator类。但是每一个iterator类中的迭代器标签却不一样。

当我们调用语句vector<int>::iterator::iterator_category时会返回random_access_iterator类的类型,当我们调用list<int>::iterator::iterator_category时会返回bidirectional_iterator类的类型。

我们再来看一下有关iterator_traits结构体的定义,

template<typename IterT>
struct iterator_traits{
typedef typename IterT::iterator_category iterator_category;//typedef typename的使用见条款42
};

假设我们通过语句iterator_traits<vector<int>::iterator>::iterator_category调用就会返回有关vector<int>迭代器iterator的类型,该语句返回random_access_iterator类型。

同理iterator_traits<list<int>::iterator>::it

posted @
2017-05-02 14:30 
llguanli 
阅读(...) 
评论(...) 
编辑 
收藏

Effective C++ 条款47的更多相关文章

  1. Effective C++ -----条款47:请使用traits classes表现类型信息

    Traits classes使得“类型相关信息”在编译期可用.它们以template和“templates特化”完成实现. 整合重载技术(overloading)后,traits classes有可能 ...

  2. EC读书笔记系列之18:条款47、48

    条款47 请使用traits classes表现类型信息 记住: ★Traits classes使得“类型相关信息”在编译期可用.它们以templates和“templates特化”完成实现 ★整合重 ...

  3. [More Effective C++]条款22有关返回值优化的验证结果

    (这里的验证结果是针对返回值优化的,其实和条款22本身所说的,考虑以操作符复合形式(op=)取代其独身形式(op),关系不大.书生注) 在[More Effective C++]条款22的最后,在返回 ...

  4. More Effective C++ 条款0,1

    More Effective C++ 条款0,1 条款0 关于编译器 不同的编译器支持C++的特性能力不同.有些编译器不支持bool类型,此时可用 enum bool{false, true};枚举类 ...

  5. Effective C++ 条款08:别让异常逃离析构函数

    1.别让异常逃离析构函数的原因 <Effective C++>第三版中条款08建议不要在析构函数中抛出异常,原因是C++异常机制不能同时处理两个或两个以上的异常.多个异常同时存在的情况下, ...

  6. Effective C++ -----条款28:避免返回handles指向对象内部成分

    避免返回handles(包括reference.指针.迭代器)指向对象内部.遵守这个条款可增加封装性,帮助const成员函数的行为像个const,并将发生“虚吊号码牌”(dangling handle ...

  7. Effective C++ -----条款21:必须返回对象时,别妄想返回其reference

    绝不要返回pointer或reference指向一个local stack对象,或返回reference指向一个heap-allocated对象,或返回pointer或reference指向一个loc ...

  8. Effective C++ -----条款19:设计class犹如设计type

    Class的设计就是type的设计.在定义一个新type之前,请确定你已经考虑过本条款覆盖的所有讨论主题. 新type的对象应该如何被创建和销毁? 对象的初始化和对象的赋值该有什么样的区别? 新typ ...

  9. Effective C++ -----条款18:让接口容易被正确使用,不易被误用

    好的接口很容易被正确使用,不容易被误用.你应该在你IDE所有接口中努力达成这些性质. “促进正确使用”的办法包括接口的一致性,以及与内置类型的行为兼容. “阻止误用"的办法包括建立新类型.限 ...

随机推荐

  1. SPOJ BGSHOOT - Shoot and kill (线段树 区间修改 区间查询)

    BGSHOOT - Shoot and kill no tags  The problem is about Mr.BG who is a great hunter. Today he has gon ...

  2. 28、Django实战第28天:个人信息展示

    从今天开始,我来完成个人中心部分,前端页面如下 1.浏览这些页面可以发现,它们和base.html是有区别的,因此,它们需要新建一个模板usercenter-base.html 2.把usercent ...

  3. websocket、文件上传

    支持情况: 浏览器实现了websocket的浏览器:Chrome Supported in version 4+ Firefox Supported in version 4+ Internet Ex ...

  4. git log 查看某文件的修改历史

    先进入此文件所在的目录下 1. git log --help 所有的git命令都可以通过git manual查看 在synopsis中可以看到公式  git log [<options>] ...

  5. 【动态规划】【记忆化搜索】【搜索】CODEVS 1262 不要把球传我 2012年CCC加拿大高中生信息学奥赛

    可以暴力递归求解,应该不会TLE,但是我们考虑记忆化优化. 设f(i,j)表示第i个数为j时的方案数. f(i,j)=f(1,j-1)+f(2,j-1)+……+f(i-1,j-1) (4>=j& ...

  6. 【分治】计算概论(A) / 函数递归练习(1)多边形游戏

    #include<cstdio> #include<algorithm> using namespace std; ],c[],s[]; int work(int L,int ...

  7. 如何让Ubuntu 14重启后,保存屏幕亮度的设置

    每次重新启动后,系统的屏幕亮度都会被调节到最大值,挺烦人的!如何让它保存设置值呢? 首先,我们必须知道自己系统的屏幕亮度取值范围,打开终端,按照下面的步骤进行: 进入backlight这个目录 cd ...

  8. Delphi 自动检测U盘插入、拔出及获取U盘盘符!

    http://qqhack8.blog.163.com/blog/static/1141479852012102133475/     Delphi 自动检测U盘插入.拔出及获取U盘盘符! u盘的 插 ...

  9. vb6转16进制

    Public Function xEncode(ByVal strEncode As String) As String If strEncode <> "" Then ...

  10. ZooKeeper服务器是用Java创建的,它在JVM上运行。

    ZooKeeper服务器是用Java创建的,它在JVM上运行. 创建配置文件 使用命令 vi conf/zoo.cfg 和所有以下参数设置为起点,打开名为 conf/zoo.cfg 的配置文件. $ ...