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. 嵌入式Linux常见问题

    Linux问题集 1 linux设置环境变量及保存地点 1. 显示环境变量HOME $ echo $HOME /home/terry 2. 设置一个新的环境变量WELCOME $ exportWELC ...

  2. Eclipse在点击运行后不能自动保存的解决

    今天在eclipse上写程序调试时,发现当我点击运行按键之后,并不能在运行前帮我自动保存,也就是说每次修改代码之后, 运行的还是前一次运行之前的代码,并不是修改之后的代码,因此通过在网上搜索解决方案之 ...

  3. Guava学习笔记:EventBus(转)

    EventBus是Guava的事件处理机制,是设计模式中的观察者模式(生产/消费者编程模型)的优雅实现.对于事件监听和发布订阅模式,EventBus是一个非常优雅和简单解决方案,我们不用创建复杂的类和 ...

  4. 14.5.7 Storing InnoDB Undo Logs in Separate Tablespaces 存储InnoDB Undo logs 到单独的表空间

    14.5.7 Storing InnoDB Undo Logs in Separate Tablespaces 存储InnoDB Undo logs 到单独的表空间 在MySQL 5.6.3,你可以存 ...

  5. Find命令, find用法,

    Find命令 用法示例:查找HOME目录下大于1M小于10M的文件$ find ~ -size +1M -size -10M 15个小时这一时刻修改的文件:find . -mmin 900 | xar ...

  6. Linux内核参数信息(Oracle相关)

    命令行:vim  /etc/sysctl.conf 查看如下两行的设置值,这里是: kernel.shmall = 2097152 kernel.shmmax = 4294967295 如果系统默认的 ...

  7. LCS小结(O(∩_∩)O~吽吽)

    LCS!~如果你在百度上搜这个的话会出来”英雄联盟冠军联赛”,orz..但是今天要讲的LCS是最长公共子序列 ,"Longest Common Subsequence "not&q ...

  8. java中int,float,long,double取值范围,内存泄露

    java中int,float,long,double取值范围是多少? 写道 public class TestOutOfBound { public static void main(String[] ...

  9. Apache+windows server2008 外网访问配置

    之前在一个服务器上部署一个apache网站,在局域网内都可以访问,但是外网始终访问不了,经常多次谷歌,把解决方案总结出来. 下面就默认部署apache自带的网站.系统:windows server20 ...

  10. MQ、JMS以及ActiveMQ

    MQ简介: MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法.应用程序通过写和检索出入列队的针对应用程序的数据(消息)来通信,而无需专用连接来链接它们.消息传 ...