什么时候写迭代器?

时间:2010-03-24 17:37:01

标签: c++ stl iterator

我知道这可能是一个愚蠢的问题..我什么时候需要编写自己的迭代器?是在设计我自己的容器类时吗?还有其他什么时候我想创建自己的迭代器吗?

示例将被挪用。

-Jon

8 个答案:

答案 0 :(得分:7)

是的,还有其他时间。举几个例子:

  1. 仅返回容器中项目的已过滤子集的filter_iterator。
  2. 仅返回对象的一部分的select迭代器。
  3. ostream_iterator,它将分隔符放在项目之前或之间,而不是在它们之后。

答案 1 :(得分:5)

任何时候你需要迭代一系列数据,并且还没有定义符合你需要的迭代器。

通常,您使用迭代器来遍历容器,但这远远不是唯一的用途。

迭代器也可以遍历数据库查询的结果,或者从流中读取输入(std::istream_iteratorstd::istreambuf_iterator已经执行此操作),或者您可能需要特殊的遍历顺序或策略。也许你想迭代“这个向量的每个成员,其索引可以被4整除”,或者“这个字符串中的每个大写字母”,或者你能想到的任何其他内容。

答案 2 :(得分:3)

当你有一个类(很可能是一个容器)并且你想让你的用户方便地遍历它而不暴露实现细节时,你需要创建一个迭代器。

当你有一个类系列(同样,很可能是容器)并且你想为你的用户提供一个统一的迭代/遍历接口时,情况更是如此,即使他们的实现非常不同(即链表与数组。)

答案 3 :(得分:2)

您需要为自己的容器类编写自己的迭代器,或者在迭代标准容器时需要非标准行为。

答案 4 :(得分:2)

实现迭代器非常有用,而且我经常这样做。迭代器是一个简单的概念,每个人都知道如何使用。迭代器允许您使用STL算法。

通常,您可以实现迭代器以简化常用操作系统API的使用,例如Windows“FindNextFile

当你写一个file_iterator(已经存在于boost中)时,你可以突然做到:

file_iterator itBegin; // initialize appropriately
file_iterator itEnd;
std::vector< HANDLE > vecFiles( itBegin, itEnd );

获取所有匹配文件的句柄列表。如果没有迭代器,必要的API调用将使您的代码更难以阅读。

将迭代器想象成简单的概念,让你写下你真正想说的内容并抽象出细节。如果必须实现一个难以理解的复杂算法,那么您希望减少代码混乱。

如果你有二维结构,例如的std ::矢量&lt; std :: vector&gt;,换句话说,一个表,其中每个内部向量需要具有相同的长度,您可能需要迭代内部向量的每个第n个元素。如果这种情况经常发生,那么当您实现迭代器而不是在整个代码中传播嵌套的for循环时,您的代码可能变得更加简单。

答案 5 :(得分:1)

我可以看到两种情况,你想要创建一个新的迭代器:

  • 对于您自己的容器类(正如您自己指出的那样)。
  • 具有现有容器类的自定义行为的迭代器。例如,STL有backwards iterators。也许你想要every_3rd_iterator只返回每三个元素?这样的迭代器可能会被实现为现有迭代器周围的适配器。

答案 6 :(得分:1)

除了过滤器和选择迭代器之外,我在c ++中编写迭代器的唯一时间是让第三方容器类与stl算法一起使用。例如

  • CORBA序列的随机访问迭代器
  • 用于CORBA序列的后插入器
  • XML Dom的双向迭代器,它将dom节点转换为迭代器,使我能够在节点兄弟节点上使用foreach和transform。

一般来说,我不喜欢编写迭代器,因为它们很难,有很多东西需要处理。但是,使用boost迭代器库可以更轻松地完成此任务。

答案 7 :(得分:0)

您可能还希望使用它们来迭代数字序列,例如Fibonacci数或素数。这些可以通过其他方式完成,可能更容易,但有时可能会使用迭代器来实现这些目的。