6

私は今日、双方向反復をサポートするコンテナの場合、このコードが有効である方法について読んでいました。

Collection c(10, 10);
auto last = --c.end();
*last;

STL のアルゴリズムに双方向イテレータ [beg, end) のペアを送信するときに、--end が定義されている必要があるのでしょうか? もしそうなら、結果は逆参照可能であるべきですか?

すなわち

void algo(T beg, T end){
    //...
    auto iter = --end;
    //...
    *iter;
} 
4

4 に答える 4

7

アルゴリズムが双方向イテレータfirstとによって定義された範囲lastを必要とする場合、その範囲が空でないという--last同じ条件下で有効である必要があります。++firstの場合に限り、範囲は空ですfirst == last

範囲が空でない場合は、範囲内--lastの最後の要素を参照するイテレータとして評価されるため、*--last有効である必要もあります。

とはいえ、特に双方向反復子を必要とする (そしてランダム アクセスを必要としない) 標準アルゴリズムはそれほど多くありません。prev, copy_backward, move_backward, reverse, reverse_copy, stable_partition, . inplace_merge_[prev|next]_permutation

それらのいくつかが何をするかを見ると、通常、アルゴリズムが範囲の終わりの反復子をデクリメントし、結果を逆参照することがわかるはずです。

ジェームズが言うように、コンテナの場合、関数はend()でイテレータを返します。が型の右辺値である場合、整形式である必要があるイテレータの一般的な要件はありません。たとえば、ポインターは双方向の反復子であり、として宣言された関数は値によってポインターを返し、整形式ではありません。実装で確認したコンテナでは、メンバー関数として定義されたクラス型が返されるため、コードがコンパイルされます。コンテナが空ではないため、これも機能します。--xxint *foo();--foo()end()operator--

この点で次の点に違いがあることに注意してください。

auto last = --c.end();

対。

auto last = c.end();
--last;

前者は右辺値をデクリメントしますが、後者は左辺値をデクリメントします。

于 2012-08-21T14:59:43.733 に答える
1

各アルゴリズムは、必要なイテレータのタイプを示します。双方向イテレータが必要な場合は、当然、デクリメントをサポートする必要があります。

可能かどうか--endは、かどうかによって異なりますend == beg

于 2012-08-21T14:29:23.320 に答える
0

双方向反復子を必要とするアルゴリズムにのみ必要です。

于 2012-08-21T14:27:41.327 に答える