简介
所有标准库类型都可以使用迭代器,但是其中只有少数几种才同时支持下标运算符,有迭代器的类型都拥有begin()
和end()
的成员函数:
/*
* b和e类型相同
* 1) b: 表示v的第一个元素
* 2) e: 尾后迭代器, 表示尾元素的下一个位置
*/
auto b = v.begin(), e = v.end();
Tips:如果容器为空,那么
begin()
和end()
返回的都是尾后迭代器。
迭代器类型
就像不知道string或vector的size_type
成员到底是什么类型一样,一般情况下我们也不知道(其实是无须知道)迭代器的精确类型。拥有迭代器的标准库类型使用iterator
和const_iterator
来表示迭代器类型:
// 可读写元素的迭代器
vector<int>::iterator it1;
string::iterator it2;
// 只能读而不能写的迭代器
vector<int>::const_iterator it3;
string::const_iterator it4;
迭代器运算符
1. 普通运算符
Tips:因为
end()
返回的迭代器类并不实际指向某个元素,所以不能对其进行递增或者解引用的操作。
*iter // 返回迭代器所指元素的引用
iter->mem // 解引用迭代器并获取该元素名为mem的成员, 等价于(*iter).mem
++iter // 令迭代器指向下一个元素
--iter // 令迭代器指向上一个元素
iter1 == iter2 // 如果两个迭代器指向同一个元素或者是同一个容器的尾后迭代器, 那么相等
iter1 != iter2
2. begin和end运算符
前面我们提到迭代器有begin
和end
运算符,它们返回的具体类型取决于对象是否是常量。如果对象是常量,那么begin
和end
返回const_iterator
,否则返回iterator
。
有时候这种默认的行为并非我们想要,如果对象只需读操作而无需写操作时最好使用常量类型,C++11新标准引入了两个新函数用于返回const_iterator
:
vector<int> vi;
auto it = vi.cbegin(); // it的类型是vector<int>::const_iterator
迭代器运算
// 迭代器加上(减去)一个整数仍得到一个迭代器, 指向的新位置与原来相比向前(向后)移动了n个位置, 结果迭代器指向容器内的一个元素或者尾后元素
iter + n
iter - n
iter += n
iter -= n
// 等于两个迭代器的距离, iter2向前移动n个元素后得到iter1
// 返回值是类型为difference_type的带符号整型数
iter1 - iter2
// 迭代器的关系运算符
>、>=、<、<=
注意事项
- 某些对vector对象的操作可能会使迭代器失效
注意push_back()
操作会使得vector对象的迭代器失效,因此不要在范围for循环中向vector对象添加元素,因为范围for循环中预存了end()
的值。