C++标准库(STL)学习笔记(二)迭代器&算法

C++标准库(STL)学习笔记(二)迭代器&算法

上次是容器,这次是迭代器和算法。迭代器可以说就是为算法服务的,所以和算法放在一起写。

1、迭代器概述

迭代器是算法使用容器的媒介。算法本身作为一个函数,对于它所操作的容器是不了解的,因此传入的迭代器必须能够给出足够的信息,使算法能够运作。

迭代器对于结构不同的迭代器,有不同的类型。其中四种类型是有链式的继承关系,分别是input,forward,bidirectional, random。input迭代器不能移动,forward迭代器只能向前移动一个单位,bidirection可以向两侧移动一个单位,random可以任意移动。output迭代器单独一类,比较特殊。

根据容器的数据结构,很容易判断它的迭代器类型。为了方便,还是整理一下。

Random:array,vector,deque,string(也可以认为是容器)。

Bidirectional:set,multiset,map,multimap。

Forward:unordered家族。

input和output主要被istream和ostream使用,可以暂时忽略。

2、iterator_traits

迭代器萃取机?大概是这么翻译。这是一个模版类,接受一个迭代器类作为模版参数。它的作用主要是回答有关迭代器和它背后容器的问题。如迭代器指向的数据类型是什么?迭代器本身的类型是什么(上面那几种)?算法调用时需要提出这些问题才能够声明合适类型的变量,做合适的操作,正常运行。

Iterator_traits类本身并没有成员变量或函数,只由一堆typedef构成,用来回答算法关于类型的提问。该类对于指针和常指针的模版参数进行了偏特化,如array和string传入的迭代器就是指针。

如果你不理解这东西有啥用的话,举个例子。假如有一个算法函数,返回传入的两个迭代器之间的最大值,并且给出了比较的算法。这时就有个问题了,写这个函数的时候你怎么知道返回值的类型是什么呢?C++不是python,不写返回类型编译器是不干的。这种时候你就可以:

template <class InputIterator>
  iterator_traits<InputIterator>::value_type
    maxValue(...){}

通过向萃取机提问,就可以获得需要的类型。还有在很多时候需要对迭代器的类型做限制。如对于random access迭代器可以做的操作不能对forward迭代器做。

3、算法函数 or 容器成员函数

很多时候,如果细心的话,你会发现有的算法是重复的。比如sort,算法库里有一个,list类中也实现了一个。这种情况下优先用类自己的函数,它肯定是对指定类有优化的。如果类本身没有实现,再去用标准库的。

4、算法函数

本来是想自己介绍几个的,想了想没必要。到这里查就行了(C++ Reference)。

看的时候要仔细看看要求,有的算法是有先决条件的。比如binary_search要求容器是排序的,他不负责帮你排序。

posted @ 2021-03-30 10:36  Napoleon0  阅读(92)  评论(0编辑  收藏  举报