STL实践与分析

--再谈迭代器【下】

三、反向迭代器【续:习题】

//P355 习题11.19
int main()
{
vector<int> iVec;
for (vector<int>::size_type index = 0; index != 10; ++index)
{
iVec.push_back(index);
} for (vector<int>::reverse_iterator r_iter = iVec.rbegin();
r_iter != iVec.rend(); ++r_iter)
{
cout << *r_iter << endl;
}
}
//习题 11.20
int main()
{
vector<int> iVec;
for (vector<int>::size_type index = 0; index != 10; ++index)
{
iVec.push_back(index);
} for (vector<int>::iterator iter = iVec.end()-1;iter >= iVec.begin(); --iter)
{
cout << *iter << endl;
}
}

//习题 11.21
int main()
{
int ia[] = {0,1,2,3,4,5,6,0,7,8,9,0,10};
vector<int> iVec(ia,ia + sizeof(ia)/sizeof(*ia)); vector<int>::reverse_iterator r_iter = find(iVec.rbegin(),iVec.rend(),0);
if (r_iter != iVec.rend())
{
cout << "element after the last 0 : " << *(-- r_iter) << endl;
}
else
{
cout << "Not found!" << endl;
}
}

//习题11.22
int main()
{
int ia[] = {0,1,2,3,4,5,6,0,7,8};
vector<int> iVec(ia,ia + sizeof(ia)/sizeof(*ia)); list<int> iList; vector<int>::reverse_iterator rbeg = iVec.rbegin(),rend; for (int i = 0; i != 3; ++i)
++ rbeg; rend = rbeg;
for (int i = 0; i != 5; ++i)
++rend; copy(rbeg,rend,back_inserter(iList)); for (list<int>::iterator iter = iList.begin(); iter != iList.end(); ++iter)
{
cout << *iter << endl;
}
}

四、const迭代器

算法要求用于指定范围的两个迭代器必须具有全然一样的类型。比方我们曾将使用的find_first_of算法:

    find_first_of(it, roster1.end(),roster2.begin(), roster2.end())

该函数调用的输入范围由it和调用roster1.end()返回的迭代器指定。算法要求用于指定范围的两个迭代器必须具有全然一样的类型。roster1.end()返回的迭代器依赖于roster1的类型。假设该容器是const对象,则返回的迭代器是const_iterator类型;否则,就是普通的iterator类型。在这个程序中,roster1不是 const对象,因而end返回的仅仅是一个普通的迭代器。

假设我们将it定义为const_iterator,那么find_first_of的调用将无法编译。用来指定范围的两个迭代器的类型不同样。it是 const_iterator类型的对象,而rotser1.end()返回的则是一个iterator对象。

五、五种迭代器

能够依据算法要求它的迭代器的提供什么类型的操作,对算法分类:

迭代器分类

输入迭代器

读,不能写:仅仅支持自增运算

输出迭代器

写,不能读:仅仅支持自增运算

前向迭代器

读和写:仅仅支持自增运算

双向迭代器

读和写:支持自增、自减运算

随机訪问迭代器

读和写:支持完整的迭代器算术运算

1、输入迭代器

可用于读取容器中的元素,可是不保证能够支持容器的写入操作。输入迭代器必须至少提供下列操作:

1)相等和不等操作符(==,!=),比較两个迭代器。

2)前置和后置的自增运算(++),使迭代器向前递进指向下一个元素。

3)用于读取元素的解引用操作符(*),此操作符仅仅能出如今赋值运算的右操作数上。

4)箭头操作符(->),这是(*it).member的同义语,也就是说,对迭代器进行解引用来获取其所关联的对象的成员。

输入迭代器仅仅能顺序使用;一旦输入迭代器自增了,就无法再用它检查之前的元素。要求在这个层次上提供支持的泛型算法包含find和 accumulate。标准库istream_iterator类型输入迭代器。

2、输出迭代器

能够视为与输入迭代器功能互补的迭代器;输入迭代器可用于向容器写入元素,但不保证能支持读取容器的内容。输入迭代器要求:

1)前置和后置的自增运算(++),使迭代器向前递进指向下一个元素。

2)解引用操作符(*),引操作符仅仅能出如今赋值运算的左操作数上。给解引用的输出迭代器赋值,将对该迭代器所指向的元素做写入操作。

输出迭代器能够要求每个迭代器的值必须正好写入一次。使用输出迭代器时,对于指定的迭代器值应该使用一次*运算,并且仅仅能用一次。输出迭代器一般用作算法的第三个实參,标记起始写入的位置。比如,copy算法使用一个输出迭代器作为它的第三个实參,将输入范围内的元素拷贝到输出迭代器指定的目标位置。标准库ostream_iterator类型输出迭代器

3、前向迭代器

用于读写指定的容器。这类迭代器仅仅会以一个方向遍历序列。前向迭代器支持输入迭代器和输出迭代器提供的全部操作,除此之外,还支持对同一个元素的多次读写。须要前向迭代器的泛型算法包含replace。

4、双向迭代器

从两个方向读写容器。出了提供前向迭代器的全部操作,还支持前置和后置的自减运算(--)。须要使用双向迭代器的泛型算法包含reverse。全部标准库容器提供的迭代器都至少达到双向迭代器的要求。

5、随机訪问迭代器

提供在常量时间内訪问容器任何位置的功能。不仅支持双向迭代器的全部功能,还支持以下的操作:

1)关系操作符<、<=、>和>=,比較两个迭代器的相对位置。

2)迭代器与整型数值n之间的加法和减法操作符+、+=、-和 -=,结果是迭代器在容器中向前(或退回)n个元素。

3)两个迭代器之间的减法操作符(--),得到两个迭代器间的距离。

4)下标操作符iter[n],这是*(iter+ n) 的同义词。

须要随机訪问迭代器的泛型算法包含sort算法。vector、deque和string迭代器是随机訪问迭代器,用作訪问内置数组元素的指针也是随机訪问迭代器。

除了输出迭代器,其它类别的迭代器形成了一个层次结构:须要低级类别迭代器的地方,可使用随意一种更高级的迭代器。

【总结】

map、set和 list类型提供双向迭代器,而string、vector和 deque容器上定义的迭代器都是随机訪问迭代器都是随机訪问迭代器,用作訪问内置数组元素的指针也是随机訪问迭代器。istream_iterator是输入迭代器,而ostream_iterator则是输出迭代器。

【关键概念:关联容器与算法】

虽然map和 set类型提供双向迭代器,但关联容器仅仅能使用算法的一个子集。问题在于:关联容器的键是const对象。因此,关联容器不能使用不论什么写序列元素的算法。仅仅能使用与关联容器绑在一起的迭代器来提供用于读操作的实參。

在处理算法时,最好将关联容器上的迭代器视为支持自减运算的输入迭代器,而不是完整的双向迭代器。

【重点理解】

C++标准为全部泛型和算术算法的每个迭代器形參指定了范围最小的迭代器种类。比如:find至少须要一个输入迭代器。replace函数至少须要一对前向迭代器。replace_copy函数的头两个迭代器必须至少是前向迭代器,第三个參数代表输出目标,必须至少是输出迭代器。

对于每个形參,迭代器必须保证最低功能。将支持更少功能的迭代器传递给函数是错误的;而传递更强功能的迭代器则没问题。

向算法传递无效的迭代器类别所引起的错误,无法保证会在编译时被捕获到。

//P358 习题11.26(d)
vector<int> iVec1,iVec2;
//...
//解释下列语句错误的原因,以及编译器是否能检測出这类错误?
sort(iVec1.begin(),iVec2.end());

C++ Primer 学习笔记_44_STL实践与分析(18)--再谈迭代器【下】的更多相关文章

  1. C++ Primer 学习笔记_43_STL实践与分析(17)--再谈迭代器【中】

    STL实践与分析 --再谈迭代器[中] 二.iostream迭代[续] 3.ostream_iterator对象和ostream_iterator对象的使用 能够使用ostream_iterator对 ...

  2. C++ Primer 学习笔记_41_STL实践与分析(15)--先来看看算法【下一个】

    STL实践与分析 --初窥算法[下] 一.写容器元素的算法 一些算法写入元素值.在使用这些算法写元素时一定要当心.必须.写入输入序列的元素 写入到输入序列的算法本质上是安全的--仅仅会写入与指定输入范 ...

  3. C++ Primer 学习笔记_29_STL实践与分析(3) --操作步骤集装箱(下一个)

    STL实践与分析 --顺序容器的操作(下) 六.訪问元素 假设容器非空,那么容器类型的front和back成员将返回容器的第一个和最后一个元素的引用. [与begin和end的对照:] 1)begin ...

  4. C++ Primer 学习笔记_32_STL实践与分析(6) --再谈string类型(下)

    STL实践与分析 --再谈string类型(下) 四.string类型的查找操作 string类型提供了6种查找函数,每种函数以不同形式的find命名.这些操作所有返回string::size_typ ...

  5. C++ Primer 学习笔记_35_STL实践与分析(9)--map种类(在)

    STL实践与分析 --map类型(上) 引: map是键-值对的集合. map类型通常能够理解为关联数组:能够通过使用键作为下标来获取一个值,正如内置数组类型一样:而关联的本质在于元素的值与某个特定的 ...

  6. C++ Primer 学习笔记_46_STL实践与分析(20)--容器特有的算法

    STL实践与分析 --容器特有的算法 与其它顺序容器所支持的操作相比,标准库为list容器定义了更精细的操作集合,使它不必仅仅依赖于泛型操作.当中非常大的一个原因就是list容器不是依照内存中的顺序进 ...

  7. C++ Primer 学习笔记_40_STL实践与分析(14)--概要、先来看看算法【上】

    STL实践与分析 --概述.初窥算法[上]     标准库容器定义的操作很少.并没有给容器加入大量的功能函数.而是选择提供一组算法,这些算法大都不依赖特定的容器类型,是"泛型"的. ...

  8. C++ Primer 学习笔记_45_STL实践与分析(19)--建筑常规算法

    STL实践与分析 --泛型算法的结构 引言: 正如全部的容器都建立在一致的设计模式上一样,算法也具有共同的设计基础. 算法最主要的性质是须要使用的迭代器种类.全部算法都指定了它的每一个迭代器形參可使用 ...

  9. C++ Primer 学习笔记_33_STL实践与分析(7) --容器适配器

    STL实践与分析 --容器适配器 引: 除了顺序容器.标准库还提供了三种顺序容器适配器:queue,priority_queue和stack.适配器是标准库中的概念.包含容器适配器,迭代器适配器和函数 ...

随机推荐

  1. PL/SQL批处理语句(BULK COLLECT子句和FORALL语句)

    Oracle为PL/SQL中的SQL相关功能提供了FORALL语句和BULK COLLECT子句,显著的增强了SQL相关功能.这两个语句一起被称作PL/SQL的批处理语句.Oracle为什么要提供这两 ...

  2. 【自由谈】城域网IPv6过渡技术——MAP技术(4)

    本节接着回答MAP技术的第三个问题:“MAP-BR的Pool是如何实现?可靠性如何提升?” 在MAP域中通过将多个MAP-BR放在同一个Pool内实现负载分担和保护倒换的.同一个Pool中的每个MAP ...

  3. 学习VC MFC开发必须了解的常用宏和指令

    1.#include指令  包含指定的文件 2.#define指令   预定义,通常用它来定义常量(包括无参量与带参量),以及用来实现那些“表面似和善.背后一长串”的宏,它本身并不在编译过程中进行,而 ...

  4. ActiveX控件的安全初始化和脚本操作 和 数字签名SIGN

    摘要:数字签名SIGN保证控件在下载时候的安全性.如果你的代码已经经过数字签名,即使用户IE的安全设置很高也能下载,安装并登记.但是在页面上初始化,或者用脚本运行这个控件,为了保证安全性,还需要进行M ...

  5. Android 手势&amp;触摸事件 MotionEvent

    1.http://blog.csdn.net/omg_2012/article/details/7881443 这篇相当好啊 2.http://blog.csdn.net/android_tutor/ ...

  6. 二分查找(非递归JAVA)

    庞果网编程英雄会上做的一道题:二分查找(非递归),和大家分享一下: public class BinarySearchClass { public static int binary_search(i ...

  7. Oracle Enterprise Manager Cloud Control 12c R4 安装配置

    准备软件 em12.1.0.4_linux64_V45344-01.zip em12.1.0.4_linux64_V45345-01.zip em12.1.0.4_linux64_V45346-01. ...

  8. 【OpenCV新手教程第14】OpenCVHough变换:霍夫变换线,霍夫变换圆汇编

    本系列文章由@浅墨_毛星云 出品.转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/26977557 作者:毛星云(浅墨) ...

  9. 【编程之美】java二进制实现重建

    package com.cn.binarytree.utils; /** * @author 刘利娟 liulijuan132@gmail.com * @version 创建时间:2014年7月20日 ...

  10. 理解Spring的Bean工厂

    一提到工厂,我们先来回顾前面学习过的工厂方法和抽象工厂模式: 工厂方法:针对产品维度,能够产生新的产品,也能够产生新的产品工厂,既能够扩展产品维度.可是假设我们想在普通工厂上生产产品系列,就会特别麻烦 ...