アルゴリズムが双方向イテレータ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;
前者は右辺値をデクリメントしますが、後者は左辺値をデクリメントします。