定义我自己的容器的迭代器

时间:2011-02-01 01:05:39

标签: c++ iterator

我对一些关于定义我自己的迭代器的概念感到困惑:

从这个:http://www.cs.northwestern.edu/~riesbeck/programming/c++/stl-iterator-define.html,似乎建议使用定义运算符的内部迭代器类。许多其他人继承基类iterator以重新定义运算符。

我对应该使用哪种方法感到很困惑。为什么有

typedef ptrdiff_t difference_type;

例如,在容器类的定义的开头?

非常感谢!

3 个答案:

答案 0 :(得分:19)

关于STL容器究竟是什么要求任何STL容器类型具有多个不同字段的C ++规范。有些内容(如begin()end())是函数,而其他内容(如iterator)是类型。这些限制也适用于迭代器。这允许C ++模板函数对其参数类型进行内省,以查找更多属性。例如,所有STL迭代器类型都必须定义包含编码其功能的类型的iterator_category字段。这样,STL算法可以基于它们接受的迭代器的功能而具有不同功能的不同实现。类示例是distance函数,它接受两个迭代器并返回它们之间的空格数。如果输入是低ForwardIteratorBidirectionalIterator,则可以通过向前推进迭代器并计算采取的步数(在O(n)中运行)来实现。如果输入是RandomAccessIterator,则可以减去迭代器以将结果输出为O(1)。

在C ++ 17之前,建议包括<iterator>标头并从std::iterator继承以自动生成您需要的必要嵌套类型(reference,{{ 1}}等。 That type is now deprecated,因此您需要手动添加pointer或专门typedef来导出此信息。

至于你需要重载的运算符,至少需要获得std::iterator_traits(前缀和后缀),++==!=(指针)取消引用),*定义。所有迭代器类型都支持这一点。对于双向迭代器或更高版本,您还应该定义->(前缀和后缀)。最后,对于随机访问迭代器,您应该支持--[]++=(备份多个步骤并减去两个迭代器),--=<><=

希望这有帮助!

答案 1 :(得分:4)

虽然@ templattypedef的答案是准确的,但也许我可以稍微澄清一下情况。

迭代器通常被定义为容器内的嵌套类。 std::iterator通常用作基类,以便您更容易定义迭代器类。你永远不会 使用std::iterator - 只是为了让这项工作更容易,并且(特别是)减少你需要输入的代码量。实际上,std::iterator已被正式弃用,因此不鼓励使用它。它可能有一天会从标准中删除(虽然我不知道它可能会被删除的具体日期)。

哦,由于与手头的问题无关的原因,有时候迭代器最好在迭代的容器类之外定义。当迭代器类定义嵌套在容器定义中时,迭代器依赖于周围类的所有模板参数。尽管如此,这很少是必要或可取的。例如,具有不同分配器的两个向量通常仍然可以具有相同的迭代器类型 - 更改分配器不会更改迭代。

答案 2 :(得分:1)

尽管使用std::iterator可能会对typedef有所帮助,但它对实际实施无效。

Boost.Iterator库有很多好处,我建议阅读boost::iterator_adaptor,它会大大减少你需要输入的代码量来定义一个新的迭代器。旧的。