本节条款的题目:请使用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. Eclipse Build all and build project not working - jar missing

    Eclipse Build all and build project not working - jar missing

  2. c程序设计语言 导言

    重在实践!! 1-10 P13 #include <stdio.h> int main() { int c; while((c = getchar()) != EOF) { ; if (c ...

  3. Codeforces 138D World of Darkraft(Multi-Nim)

    [题目链接] http://codeforces.com/problemset/problem/138/D [题目大意] H*W的棋盘中每个点都是L.R.X三者之一,两人轮流选一个点, 若为L则向左下 ...

  4. [CF494D]Birthday

    题意:给一棵带边权的树,定义如下的一些东西 $S(x)$表示以$x$为根的子树中的节点组成的集合 $d(u,v)$表示$u$和$v$之间的距离 $f(u,v)\sum\limits_{x\in S(v ...

  5. golang垃圾回收

    常见GC算法 我总结了一下常见的 GC 算法.分别是:引用计数法.Mark-Sweep法.三色标记法.分代收集法. 1. 引用计数法 原理是在每个对象内部维护一个整数值,叫做这个对象的引用计数,当对象 ...

  6. no such file or directory : 'users/shikx/xxx/xxx/Appirater.m'

    删除此处红色的.m文件即可

  7. BlockTransferService 实现

    spark的block管理是通过BlockTransferService定义的方法从远端获取block.将block存储到远程节点.shuffleclient生成过程就会引入blockTransfer ...

  8. 【sql】关联查询+表自关联查询

    表: 经销商 dealer   字段 uid  parent_uid  name 联系人 contact  字段 uid  dealer_id  contact_main 需求: 想要查询到经销商的信 ...

  9. 你真的了解try{ return }finally{}中的return?(转载)

    发现一篇有意思的博文,分享一下 谁能给我我解释一下这段程序的结果为什么是:2.而不是:3 代码如下: class Test { public int aaa() { int x = 1; try { ...

  10. Android Design Support Library介绍之:环境搭建

    在2015年的GoogleIO大会上.具体的Material Design设计规范出炉了.全新的Android Design Support Library 格.更让人开心的是,这些很酷的风格能够通过 ...