本节条款的题目:请使用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. 学习LSM(Linux security module)之一:解读yama

    最近打算写一个基于LSM的安全模块,发现国内现有的资料极少.因此打算自己琢磨一下.大致的学习路线如下: 由易至难使用并阅读两到三个安全模块->参照阅读模块自己实现一个安全模块->在自己实现 ...

  2. 【莫队算法】【权值分块】bzoj3585 mex

    orz PoPoQQQ. 本来蒟蒻以为这种离散化以后就对应不起来的题不能权值分块搞的说. ……结果,实际上>n的权值不会对答案作出贡献. #include<cstdio> #incl ...

  3. 【模拟】洛谷 P1328 NOIP2014提高组 day1 T1 生活大爆炸版石头剪刀布

    把所有情况打表,然后随便暴力. #include<cstdio> using namespace std; int n,an,bn,p1,p2; ],b[]; ][]; int ans1, ...

  4. 【bzoj2142】【礼物】拓展Lucas定理+孙子定理

    (上不了p站我要死了,侵权度娘背锅) Description 一年一度的圣诞节快要来到了.每年的圣诞节小E都会收到许多礼物,当然他也会送出许多礼物.不同的人物在小E 心目中的重要性不同,在小E心中分量 ...

  5. 线程协作-Semaphore并发限制

    Semaphore(信号量)是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源.

  6. Eclipse快速补全快捷键Ctrl+1修改为Android Studio的Alt+Enter

    步骤: Window ->Preferences->key-> type filter text 下输入quick fix(这个是快速补全的快捷键)改为Alt+Enter 下面的wh ...

  7. C#将json字符串解析成对象

    首先我们在客户端生成json字符串,通过ajax把该字符串传到服务器端   //这是一个以id,email,age的json字符串   var jdata="[{\"id\&quo ...

  8. linux dd命令实例讲解

    转:http://blog.chinaunix.net/uid-28549627-id-3922282.html 提到linux 系统中的dd命令,各位技术博友大多都很熟悉,用法也是好多,今天主要跟大 ...

  9. xargs: How To Control and Use Command Line Arguments

    参考: http://www.cyberciti.biz/faq/linux-unix-bsd-xargs-construct-argument-lists-utility/ http://linux ...

  10. linux/mac系统的软链接文件与硬链接文件

    1.硬连接只能使用在文件上,不可以使用在文件夹上.至于文件前面的硬链接数字的含义如下: 如图标注区,为硬连接的数量,文件前的数字1表示没有硬链接.文件夹前面的数字至少是2,含义是这个文件夹是空文件夹, ...