ForwardIterators是否必须是OutputIterators?我当前的STL实现(VS2012)从forward_iterator_tag
和input_iterator_tag
派生output_iterator_tag
,但我在标准[N3485]中找不到此要求。
答案 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
,我只能假设它是一个错误。