本节条款的题目:请使用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. noi题库 1.7 字符串 10到第15题

    10:简单密码 描述 Julius Caesar曾经使用过一种很简单的密码.对于明文中的每个字符,将它用它字母表中后5位对应的字符来代替,这样就得到了密文.比如字符A用F来代替.如下是密文和明文中字符 ...

  2. [BZOJ1146][CTSC2008]网络管理Network(二分+树链剖分+线段树套平衡树)

    题意:树上单点修改,询问链上k大值. 思路: 1.DFS序+树状数组套主席树 首先按照套路,关于k大值的问题,肯定要上主席树,每个点维护一棵权值线段树记录它到根的信息. 关于询问,就是Que(u)+Q ...

  3. 【分块】【哈希】bzoj3578 GTY的人类基因组计划2

    每个房间用一个集合来维护,具体来说,就是给1-n的数每个数一个long long的hash值,往集合S里insert(i),就是S^=HASH[i]:erase(i),也是S^=HASH[i]. 用m ...

  4. 【莫队算法】【权值分块】bzoj3339 Rmq Problem

    如题. #include<cstdio> #include<algorithm> #include<cmath> using namespace std; #def ...

  5. Android Studio 下使用git -- 个人,本地版本控制

    第一步:下载安装git 下载地址 : https://git-scm.com/downloads 第二步:Android Studio 下配置git路径. 配置之后,Test弹出如下成功的提示即可. ...

  6. Java杂谈2——引用与跟搜索算法

    Java中的引用 Java“引用”的概念源于C++,原本的定义相当有限:一个引用(Reference)代表的内存通常用于指向另一块内存区域的起始地址.通过引用类型保存的起始地址,可以找到这个引用所指向 ...

  7. delphi执行cmd命令和bat文件

    转载地址:http://blog.csdn.net/hutao1101175783/article/details/42807063 cmd:='echo d | Xcopy '+BasePath+' ...

  8. Linux下打包命令tar

    转:http://blog.chinaunix.net/uid-29021161-id-3922752.html Linux下最常用的打包程序是tar,用tar命令打成的包文件通常以.tar结尾 1. ...

  9. JS版汉字与拼音互转终极方案,附简单的JS拼音输入法

    原文:http://www.cnblogs.com/liuxianan/p/pinyinjs.html 前言 网上关于JS实现汉字和拼音互转的文章很多,但是比较杂乱,都是互相抄来抄去,而且有的不支持多 ...

  10. easyui-validatebox 的简单长度验证

    验证: 页面代码: <form id="invoiceEdit"> <input id="fpdm" name="fpdm" ...