常见的坑
所有标准库容器都支持迭代器,而只有少数几种支持下标运算符。
string
虽然不是容器,但是支持很多容器的操作。容器不为空时:
begin()
返回的是容器中第一个元素的位置;end()
返回的是容器中最后一个元素的后一个位置。容器为空时:
begin()
和end()
返回的都是最后一个元素的后一个位置。任何可能改变容器大小的操作都会使容器的迭代器失效。
必须要理解的点
和指针类似的是,迭代器支持对对象的间接访问。
和指针不同的是,获取迭代器不使用取地址符,有迭代器的类型都拥有返回迭代器的成员函数,如
begin()
,end()
。所有迭代器都支持的运算:
运算符 例子 含义 * *iter
返回迭代器 iter
指向元素的引用-> iter->mem
解引用 iter
并获取该元素名为mem
的成员,即(*iter).mem
++ ++iter
令 iter
指向当前元素的后一个元素– --iter
令 iter
指向当前元素的前一个元素== iter1 == iter2
如果两个迭代器指向相同的元素返回 true
,否则返回false
!= iter1 != iter2
上面例子的反面 迭代器的类型有两种:
iterator
和const_iterator
。vector<int>::iterator itv; // 可用于读写vector<int>中的元素 string::iterator its; // 可用于读写string对象中的元素 vector<int>::const_iterator citv; // 只能读取元素 string::const_iterator cits; // 只能读取元素
begin()
和end()
返回哪一种取决于对象本身是否被const
修饰。C++11 中引入了
cbegin()
和cend()
来专门返回const_iterator
。认定一种类型是迭代器当且仅当它支持一套操作,这套操作能使我们访问容器内的元素或从某一个元素移动到另一个元素。
vector
和string
的迭代器支持的额外的运算:运算 含义 iter + n
运算得到一个新迭代器,指向当前元素的后 n 个元素的位置 iter - n
运算得到一个新迭代器,指向当前元素的前 n 个元素的位置 iter += n
运算得到的新迭代器赋值给 iter
iter -= n
同上 iter1 - iter2
两个迭代器之间的距离,可正可负 >
,<
,<=
,>=
同两类型的下标运算符中的数字的关系,位置靠前的较小
建议
- 一般不在意迭代器的类型,因此使用
auto
来标注。 - 循环结束的判断条件习惯使用迭代器和
!=
,这样可以不用在意容器类型。 - 凡是使用了迭代器的循环体中都不能有改变容器大小的操作如
push_back()
。