迭代器
每种容器类型都提供若干共同工作的迭代器类型。与容器类型一样,所有迭代器具有相同的接口:如果某种迭代器支持某种操作,那么支持这种操作的其他迭代器也会以相同的方式支持这种操作。例如,所有容器迭代器都支持以解引用运算从容器中读入一个元素。类似地,容器都提供自增和自减操作符来支持从一个元素到下一个元素的访问。
常用迭代器运算
*iter : 返回迭代器 iter 所指向的元素的引用
iter->mem : 对 iter 进行解引用,获取指定元素中名为 mem 的成员。等效于 (*iter).mem
++iter iter++ : 给 iter 加 1,使其指向容器里的下一个元素
–iter iter-- : 给 iter 减 1,使其指向容器里的前一个元素
iter1 == iter2
iter1 != iter2 :比较两个迭代器是否相等(或不等)。当两个迭代器指向同一个容器中的同一个元素,或者当它们都指向同一个容器的超出末端的下一位置时,两个迭代器相等
vector 和 deque 容器的迭代器提供额外的运算
C++ 定义的容器类型中,只有 vector 和 deque 容器提供下面两种重要的运算集合:迭代器算术运算(第 3.4.1 节),以及使用除了 == 和 != 之外的关系操作符来比较两个迭代器(== 和 != 这两种关系运算适用于所有容器)。
- vector 和 deque 类型迭代器支持的操作
iter + n
iter - n :在迭代器上加(减)整数值 n,将产生指向容器中前面(后面)第 n 个元素的迭代器。新计算出来的迭代器必须指向容器中的元素或超出容器末端的下一位置
iter1 += iter2 :这里迭代器加减法的复合赋值运算:将 iter1 加上或减去 iter2 的运算结果赋给 iter1
iter1 - iter2 :两个迭代器的减法,其运算结果加上右边的迭代器即得左边的迭代器。这两个迭代器必须指向同一个容器中的元素或超出容器末端的下一位置
- 只适用于 vector 和 deque 容器 >, >=, <, <= :迭代器的关系操作符。当一个迭代器指向的元素在容器中位于另一个迭代器指向的元素之前,则前一个迭代器小于后一个迭代器。关系操作符的两个迭代器必须指向同一个容器中的元素或超出容器末端的下一位置。
关系操作符只适用于 vector 和 deque 容器,这是因为只有这种两种容器为其元素提供快速、随机的访问。它们确保可根据元素位置直接有效地访问指定的容器元素。这两种容器都支持通过元素位置实现的随机访问,因此它们的迭代器可以有效地实现算术和关系运算。
举例
- vector
vector<int>::iterator iter = vec.begin() + vec.size()/2;
计算 vector 对象的中点位置
- list
// copy elements from vec into ilist list<int> ilist(vec.begin(), vec.end()); ilist.begin() + ilist.size()/2; // error: no addition on list iterators
用法示列
(a) vector::iterator it = ivec.begin();
这个用法是正确的。it 被声明为 vector 的迭代器,并且被赋值为 ivec 的开始迭代器。
(b) list::iterator it = ilist.begin()+2;
这个用法是错误的。std::list 的迭代器不支持加法运算符。如果你想要前进到 list 的第三个元素,你应该使用循环或者 std::advance 函数。
© vector::iterator it = &svec[0];
这个用法是错误的。在C++中,你不能直接使用 & 运算符来获取 vector 的第一个元素的地址,然后将其赋给迭代器。正确的方式是使用 svec.begin()。
(d) for (vector::iterator it = svec.begin(); it != 0; ++it)
这个用法是错误的。在C++中,迭代器的比较操作符是 == 和 !=,而不是 != 0。迭代器本身不与任何数值比较,它们只与其它迭代器比较。
正确的迭代器声明和循环应该像这样:
for (vector<string>::iterator it = svec.begin(); it != svec.end(); ++it) { // ... }
在这个循环中,迭代器 it 从 svec 的开始迭代器开始,一直遍历到 svec.end(),即 vector 的结束迭代器。每次循环迭代器 it 都会通过 ++it 向前移动。
std::advance讲解
函数原型
template <class InputIt, class Distance> void advance(InputIt& it, Distance n);
- InputIt 是迭代器的类型。
- Distance 是步数的类型,通常是一个整数。
std::advance 接受两个参数:一个迭代器引用 it 和一个表示步数的 n。如果 n 是正数,函数将迭代器向前移动 n 步;如果 n 是负数,函数将迭代器向后移动 -n 步。
// 向后移动3步,回到开始位置 std::advance(it, -3);
std::advance 的行为取决于迭代器的类别。对于只读迭代器(如 std::list 的迭代器),std::advance 只允许正数步进。对于随机访问迭代器(如 std::vector 或 std::deque 的迭代器),std::advance 可以处理正数和负数步进。