10

ForwardIterators は OutputIterators である必要がありますか? 私の現在の STL 実装 (VS2012) は と の両方から派生しforward_iterator_tagていますが、標準 [N3485] でこの要件を見つけることができません。input_iterator_tagoutput_iterator_tag

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 に答える