【问题标题】:Are Forward-Iterators Output-Iterators?前向迭代器是输出迭代器吗?
【发布时间】:2012-12-13 01:51:22
【问题描述】:

ForwardIterators 必须是 OutputIterators 吗?我当前的 STL 实现(VS2012)从 input_iterator_tagoutput_iterator_tag 派生 forward_iterator_tag,但我在标准 [N3485] 中找不到这个要求。

【问题讨论】:

    标签: c++ iterator-traits


    【解决方案1】:

    在 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,但它被关闭为不是缺陷,因为第一个引用在该部分的“介绍性文本”中,并且将来可能会被改写(确实如此)。


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

    不过,如果我们看一下implementation of the iterator tags,我们会发现forward_iterator_tag 仍然只继承自input_iterator_tag

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

    【讨论】:

    • 但请注意,这似乎与 SGI 定义不同,其中文档说 ForwardIterator 是“InputIterator 和 OutputIterator 的改进”,即存在 ForwardInputIterator 和 ForwardOutputIterator 但不仅仅是 ForwardIterator,这个概念不能独善其身。
    • @BenVoigt 这似乎在 C++03 和 C++11 之间发生了变化。编辑:等等,实际上,这令人困惑。
    • @sftrabbit:感谢您澄清这一点。现在将迭代器标记为转发和输出的规范方法是什么? (只是引入一个新的私有标签,继承自两者,还是有不同的方式?)
    • @MFH 我实际上也在想同样的事情。也许值得另一个问题。
    • @sftrabbit:我添加了一个新问题 (stackoverflow.com/questions/14062297/…)。会有什么答案会很有趣......
    猜你喜欢
    • 2012-10-27
    • 2020-01-21
    • 2011-09-20
    • 2014-01-20
    • 2011-07-09
    • 2018-02-16
    • 2010-10-27
    • 2012-02-10
    • 2012-02-03
    相关资源
    最近更新 更多