关闭

C++学习笔记:迭代器

206人阅读 评论(0) 收藏 举报

迭代器提供按元素逐个访问一个序列的方法。序列的内容可以是数值、字符或几乎任何类型的对象。标准容器(如向量)提供访问容器内容的迭代器,有的标准迭代器还允许访问输入流与输出流。标准算法仅使用迭代器操作序列。

C++有五类不同的迭代器:输入迭代器、输出迭代器、前向迭代器、双向迭代器、随机访问迭代器。输入、输出迭代器功能最少,随机访问迭代器功能最多。在任何使用功能少的迭代器的地方均可以利用功能多的迭代器替代。几种迭代器的主要功能:

输入迭代器:输入迭代器只支持输入。这种迭代器的每次迭代只能执行一次读操作(通过单目*操作符),不能修改迭代器引用的数据项。++操作符可以递增到下一个输入数据项。可以对这种迭代器比较相等性与不等性,但只有将一个迭代器与末端迭代器进行比较才是有意义的。通常情况下不能通过比较两个输入迭代器来判定它们是否引用相同的数据项。

输出迭代器:输出迭代器只支持输出。可以向这种迭代器赋予一个数据项(通过对赋值表达式左边的迭代器使用*操作符),但不能从迭代器读取数据。每次迭代只能修改一次迭代器的值,++操作符可将其递增到下一输出数据项。

不能对输出迭代器比较相等性与不等性。

另外,在处理输出迭代器是要注意:必须确保迭代器真实写入的地方有足够的空间存储输出数据整体,任何错误都将导致不确定的行为。

前向迭代器:前向迭代器出具有输入输出迭代器的全部功能外,还有更多功能。可以自由的读写一个迭代器的数据项,并且可以随意的操作任意多次。++操作符可以递增到下一数据项。==与!=操作符用于比较迭代器,检测它们是否引用相同的数据项或是否达到末端。

双向迭代器:双向迭代器不仅具有前向迭代器的所有功能,而且支持--操作符,这可以是迭代器移回到之前所在的数据项。与任何迭代器一样,需要确保迭代器不超过区间末尾,也不引用到区间起始之前。

随机访问迭代器:随机访问迭代器是最强大的迭代器,它具有其他所有迭代器的所有功能,此外还可以通过加上或减去整数的方式使迭代器移动任意量。

const_iterator与const iterator

如果你需要对区间内的数据只读,而所用的迭代器可能是前向迭代器,双向迭代器或随机访问迭代器,你可能真正需要的仅是一个输入迭代器。你也许认为将迭代器声明为const会有用,那么看下面的程序:

#include <iostream>
#include <ostream>

#include "data.hpp"

int main()
{
  intvector data;
  read_data(data);
  const intvec_iterator iter(data.begin());
  std::advance(iter, data.size() / 2); // move to middle of vector
  if (not data.empty())
    std::cout << "middle item = " << *iter << '\n';
}

=================================================

data.hpp:

#ifndef DATA_HPP_
#define DATA_HPP_

#include <algorithm>
#include <iostream>
#include <iterator>
#include <ostream>
#include <vector>

typedef std::vector<int> intvector;
typedef intvector::iterator intvec_iterator;

template<class Container>
void read_data(Container& data)
{
  data.clear();
  data.insert(data.begin(), std::istream_iterator<typename Container::value_type>(std::cin),
              std::istream_iterator<typename Container::value_type>());
}

template<class Container>
void write_data(Container const& data)
{
  std::cout << "{ ";
  std::copy(data.begin(), data.end(),
            std::ostream_iterator<typename Container::value_type>(std::cout, " "));
  std::cout << "}\n";
}
#endif

编译器会拒绝编译该程序,原因在于iter是const的。你不能修改这个迭代器,因此不能将其移动到向量中间。不能将迭代器本身声明为const,而需要告编译器你希望迭代器引用const数据。如果向量本身是const的,其begin()函数将返回这样一种迭代器;可以自由的修改迭代器的位置,但不能修改迭代器引用的值。这种函数返回的迭代器名字是const_iterator。

所以要想使上面的程序成功编译,则只需将const intvec_iterator iter(data.begin());修改为intvector::const_iterator iter(data.begin());


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:14799次
    • 积分:248
    • 等级:
    • 排名:千里之外
    • 原创:10篇
    • 转载:3篇
    • 译文:0篇
    • 评论:3条
    文章分类
    最新评论