加入收藏 | 设为首页 | 会员中心 | 我要投稿 大连站长网 (https://www.0411zz.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 编程要点 > 语言 > 正文

C++ STL list迭代器及用法 细说版

发布时间:2022-07-16 07:04:51 所属栏目:语言 来源:互联网
导读:只有运用迭代器,才能访问 list 容器中存储的各个元素。list 模板类提供了如表 1 所示的这些迭代器函数。 表 1 list 容器迭代器函数 迭代器函数 功能 begin() 返回指向容器中第一个元素的双向迭代器(正向迭代器)。 end() 返回指向容器中最后一个元素所在
  只有运用迭代器,才能访问 list 容器中存储的各个元素。list 模板类提供了如表 1 所示的这些迭代器函数。
 
  表 1 list 容器迭代器函数
  迭代器函数 功能
  begin() 返回指向容器中第一个元素的双向迭代器(正向迭代器)。
  end() 返回指向容器中最后一个元素所在位置的下一个位置的双向迭代器。(正向迭代器)。
  rbegin() 返回指向最后一个元素的反向双向迭代器。
  rend() 返回指向第一个元素所在位置前一个位置的反向双向迭代器。
  cbegin() 和 begin() 功能相同,只不过在其基础上,正向迭代器增加了 const 属性,即不能用于修改元素。
  cend() 和 end() 功能相同,只不过在其基础上,正向迭代器增加了 const 属性,即不能用于修改元素。
  crbegin() 和 rbegin() 功能相同,只不过在其基础上,反向迭代器增加了 const 属性,即不能用于修改元素。
  crend() 和 rend() 功能相同,只不过在其基础上,反向迭代器增加了 const 属性,即不能用于修改元素。
  除此之外,C++ 11 新添加的 begin() 和 end() 全局函数也同样适用于 list 容器。即当操作对象为 list 容器时,其功能分别和表 1 中的 begin()、end() 成员函数相同。
 
  注意,list 容器的底层实现结构为双向链表,这种表示仅是为了方便理解各个迭代器函数的功能。
 
  从图 2 可以看出,这些成员函数通常是成对使用的,即 begin()/end()、rbegin()/rend()、cbegin()/cend()、crbegin()/crend() 各自成对搭配使用。其中,begin()/end() 和 cbegin/cend() 的功能是类似的,同样 rbegin()/rend() 和 crbegin()/crend() 的功能是类似的。
 
  前面章节已经详细介绍了 array、vector、deque 容器的迭代器,和它们相比,list 容器迭代器最大的不同在于,其配备的迭代器类型为双向迭代器,而不再是随机访问迭代器。
 
  这意味着,假设 p1 和 p2 都是双向迭代器,则它们支持使用 ++p1、 p1++、 p1--、 p1++、 *p1、 p1==p2 以及 p1!=p2 运算符,但不支持以下操作(其中 i 为整数):
  p1[i]:不能通过下标访问 list 容器中指定位置处的元素。
  p1-=i、 p1+=i、 p1+i 、p1-i:双向迭代器 p1 不支持使用 -=、+=、+、- 运算符。
  p1<p2、 p1>p2、 p1<=p2、 p1>=p2:双向迭代器 p1、p2 不支持使用 <、 >、 <=、 >= 比较运算符。
  有关迭代器类别和功能的具体介绍,可阅读 《C++ STL迭代器》一节。
 
  下面这个程序演示了如何使用表 1 中的迭代器遍历 list 容器中的各个元素。
  #include <iostream>
  #include <list>
  using namespace std;
  int main()
  {
      //创建 list 容器
      std::list<char> values{'h','t','t','p',':','/','/','c','.','b','i','a','n','c','h','e','n','g','.','n','e','t'};
      //使用begin()/end()迭代器函数对输出list容器中的元素
      for (std::list<char>::iterator it = values.begin(); it != values.end(); ++it) {
          std::cout << *it;
      }
      cout << endl;
      //使用 rbegin()/rend()迭代器函数输出 lsit 容器中的元素
      for (std::list<char>::reverse_iterator it = values.rbegin(); it != values.rend();++it) {
          std::cout << *it;
      }
      return 0;
  }
  输出结果为:
  http://c.biancheng.net
  ten.gnehcnaib.c//:ptth
 
  注意,程序中比较迭代器之间的关系,用的是 != 运算符,因为它不支持 < 等运算符。另外在实际场景中,所有迭代器函数的返回值都可以传给使用 auto 关键字定义的变量,因为编译器可以自行判断出该迭代器的类型。
 
 
  值得一提的是,list 容器在进行插入(insert())、接合(splice())等操作时,都不会造成原有的 list 迭代器失效,甚至进行删除操作,而只有指向被删除元素的迭代器失效,其他迭代器不受任何影响。
 
  举个例子:
  #include <iostream>
  #include <list>
  using namespace std;
  int main()
  {
      //创建 list 容器
      std::list<char> values{'h','t','t','p',':','/','/','c','.','b','i','a','n','c','h','e','n','g','.','n','e','t'};
      //创建 begin 和 end 迭代器
      std::list<char>::iterator begin = values.begin();
      std::list<char>::iterator end = values.end();
      //头部和尾部插入字符 '1'
      values.insert(begin, '1');
      values.insert(end, '1');
      while (begin != end)
      {
          std::cout << *begin;
          ++begin;
      }
      return 0;
  }
  运行结果为:
  http://c.biancheng.net1
 
  可以看到,在进行插入操作之后,仍使用先前创建的迭代器遍历容器,虽然程序不会出错,但由于插入位置的不同,可能会遗漏新插入的元素。

(编辑:大连站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!