在 C++11 中,不,前向迭代器不需要是输出迭代器。输出迭代器要求就像迭代器可以具有的一组额外要求,无论它满足其他迭代器要求如何。前向迭代器只需是输入迭代器(§24.2.5/1):
如果满足以下条件,则类或指针类型 X 满足前向迭代器的要求:
In fact, a forward iterator meets the output iterator requirements only if it is a mutable iterator to a sequence of copy-assignable types†.
† or a constant iterator to a sequence of types with operator=(...) const
defined with mutable members.
更重要的是,迭代器标签由标准具体定义为(§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 中的定义相同。有一个缺陷报告 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1808.html#476对于这种矛盾的措辞,但它被关闭为“不是缺陷”,因为第一个引用位于该部分的“介绍性文本”中,并且将来可能会被重新措辞(确实如此)。
The SGI 前向迭代器的定义 http://www.sgi.com/tech/stl/ForwardIterator.html作为输入和输出迭代器的细化给出(感谢评论中的@BenVoigt)。
尽管如此,如果我们看一下迭代器标签的实现 http://www.sgi.com/tech/stl/stl_iterator_base.h,我们发现forward_iterator_tag
仍然只是继承自input_iterator_tag
.
看起来这在过去是一个相当混乱的领域,但如果 VS2012 正在定义forward_iterator_tag
作为继承自两者output_
- and input_iterator_tag
,我只能假设这是一个错误。