• 如果容器为空,begin、end均返回尾后迭代器。

  • 迭代器操作:

    • *iter:返回所指元素引用
    • iter->mm:解引用iter并获取该元素名为mem的成员。等价于(*iter).mem
    • ++iter、–iter
    • iter1 == iter2、iter1 != iter2
  • 若容器对象为const常量,则只能使用const_iterator,只读不可写;否则既可使用const_iterator也可使用iterator。

  • cbegin()、cend()返回常量迭代器。

  • 迭代器失效:(增删元素可能会导致迭代器失效,修改元素不会)

    • vector
      • push_back(val)触发扩容,所有迭代器失效。
      • insert(val)触发扩容,所有迭代器失效;insert(val)导致后面元素移动,后面被移动部分迭代器失效,前面不失效。
      • erase(val)导致后面元素移动,后面被移动部分迭代器失效,前面不失效。
    • deque
      • 插删元素导致迭代器失效的情况较复杂,避免deque增删容器后仍使用原迭代器。详细内容参考其他大佬的博客。
    • list
      • 因存储空间不连续,使用链表来实现,因此插入、删除一个元素,不会导致其他迭代器失效。
    • set、map
      • 关联式容器使用红黑树实现,插入删除一个元素,不会导致其他迭代器失效。
    • 解决方案:使用erase()、insert()等函数返回的新迭代器。

迭代器属性

  • 迭代器属性

    1. 所有迭代器都提供的属性:p++,*p,p = p1

    2. 输入迭代器:只读(额外提供:p == p1,p != p1)

    3. 输出迭代器:只写

    4. 正向迭代器:读写(提供输入输出迭代器的所有功能)

    5. 双向迭代器:读写(提供正向迭代器的所有功能,额外提供:p–)

    6. 随机访问迭代器:读写(提供双向迭代器的所有功能,额外提供:p += i,p + i,p[i] 返回元素引用,p < p1,p - p1 计算两迭代器间的距离,即元素个数)

    vector、deque、string、array:5

    list:4

    forward_list:3

    set、multiset:4

    map、multimap:4

    stack、queue、priority_queue:不支持迭代器

    (find()方法至少需要输入迭代器;sort()方法至少需要随机访问迭代器)

1
2
3
4
5
6
7
// 关于随机访问迭代器的 p[i],其中p为迭代器

vector<int> vec = { 6,7,8,9,10,11,12,13 };
auto itor = vec.begin() + 2; // 指向 8
int res = itor[2]; // 指向 10 (注意这里不是vec[2],是itor[2])
itor[2] = 50; // vec {6,7,8,9,50,11,12,13}
return 0;
  • 反向迭代器
    • 先翻转各元素位置,然后将反向迭代器当做正向迭代器处理。
    • 流迭代器不支持递减运算;不可能从一个forward_list或一个流迭代器创建反向迭代器。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 向sort传递一对反向迭代器来实现递减排序
sort(vec.begin(), vec.end()); // 正序
sort(vec.rbegin(), vec.rend()); // 倒序



string line = "FIRST,MIDDLE,LAST";
// 在一个逗号分割的列表中查找第一个元素。返回首个逗号位置的迭代器(string::const_iterator),否则返回cend()
auto comma = find(line.cbegin(), line.cend(), ',');
string res_1 = string(line.cbegin(), comma); // 返回 FIRST

// 在一个逗号分隔的列表中查找最后一个元素。返回最后一个逗号位置的迭代器(string::const_reverse_iterator),否则返回crend()
auto rcomma = find(line.crbegin(), line.crend(), ',');
string res_2 = string(line.crbegin(), rcomma); // 返回 TSAL !!!

// 需要做的是,将rcomma转换回一个普通迭代器,能在line中正向移动。通过base成员函数完成转换
// 反向迭代器与转换后的普通迭代器,两者不是指向相同的元素,而是指向相邻的元素
string res_3 = string(rcomma.base(), line.end()); // 返回 LAST

反向迭代器和普通迭代器的关系