10

ForwardIterators 是否必须是 OutputIterators?我当前的 STL 实现 (VS2012) 源自forward_iterator_tagand input_iterator_tagoutput_iterator_tag但我在标准 [N3485] 中找不到这个要求。

4

1 回答 1

13

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

类或指针类型 X 满足前向迭代器的要求,如果:

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

事实上,前向迭代器只有在它是可复制分配类型序列的可变迭代器时才满足输出迭代器要求†</sup>。

† 或常量迭代器,指向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 中的相同。这个矛盾的措辞有一个缺陷报告,但它被关闭为不是缺陷,因为第一个引用在该部分的“介绍性文本”中,并且将来可能会重新措辞(确实如此)。


前向迭代器的SGI 定义作为输入和输出迭代器的改进给出(感谢评论中的@BenVoigt)。

尽管如此,如果我们看一下迭代器标签的实现,我们会发现它forward_iterator_tag仍然只继承自input_iterator_tag

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

于 2012-12-27T17:30:35.797 回答