前向迭代器是输出迭代器吗?

时间:2012-12-27 17:25:25

标签: c++ iterator-traits

ForwardIterators是否必须是OutputIterators?我当前的STL实现(VS2012)从forward_iterator_taginput_iterator_tag派生output_iterator_tag,但我在标准[N3485]中找不到此要求。

1 个答案:

答案 0 :(得分:13)

在C ++ 11中,不需要,前向迭代器不需要输出迭代器。输出迭代器要求就像迭代器可以拥有的一组额外要求,而不管它遇到的其余迭代器要求。前向迭代器只需要是输入迭代器(第24.2.5 / 1节):

  

如果符合以下情况,则类或指针类型X满足前向迭代器的要求:

     
      
  • X满足输入迭代器的要求
  •   
  • ...
  •   

实际上,只有当前向迭代器是一系列可复制的类型的可变迭代器时,它才符合输出迭代器的要求。

†或operator=(...) const定义为可变成员的类型序列的常量迭代器。

更重要的是,迭代器标签由标准专门定义为(§24.4.3/ 2):

namespace std {
  struct input_iterator_tag { };
  struct output_iterator_tag { };
  struct forward_iterator_tag: public input_iterator_tag { };
  struct bidirectional_iterator_tag: public forward_iterator_tag { };
  struct random_access_iterator_tag: public bidirectional_iterator_tag { };
}

如您所见,forward_iterator_tag应该只从input_iterator_tag继承。


在C ++ 03中,声明前向迭代器满足输入和输出迭代器的要求:

  

前向迭代器满足输入和输出迭代器的所有要求,并且只要指定了任何一种类型,就可以使用它。

但是这在以下段落中是矛盾的,声明一个常量的前向迭代器不能满足输出迭代器的要求:

  

除了类别之外,正向,双向或随机访问迭代器也可以是可变的或常量的,这取决于表达式* i的结果是作为引用还是作为对常量的引用。常量迭代器不满足输出迭代器的要求,并且表达式* i(对于常量迭代器i)的结果不能在需要左值的表达式中使用。

但是,迭代器标记的定义与C ++ 11中的相同。这个相互矛盾的措辞有一个defect report,但由于第一个引用是在该部分的“介绍性文本”中,并且将来可能会被改写(它是),因此它被关闭为非缺陷。 / p>


SGI definition of a forward iterator是对输入和输出迭代器的改进(感谢评论中的@BenVoigt)。

尽管如此,如果我们查看implementation of the iterator tags,我们发现forward_iterator_tag仍然只是从input_iterator_tag继承。

过去看起来这是一个相当混乱的领域,但如果VS2012将forward_iterator_tag定义为继承output_ - 和input_iterator_tag,我只能假设它是一个错误。