9

C ++では、OutputIterator型Xが形式の式をサポートしている必要があります。r++ここで、はのrインスタンスですX。この接尾辞の増分は、意味的に次のものと同等である必要があります。

(*) { X tmp = r; ++r; return tmp; }

に変換可能な型を返す必要がありX const&ます。C ++ 11では、24.2.4を参照してください(ただし、これは新しいものではありません)。同じセクションで、それは言います

出力イテレータのアルゴリズムは、同じイテレータを2回通過しようとしないでください。それらはシングルパスアルゴリズムである必要があります。

上記の(*)が与えられた場合、次のように戻り値をコピーするとします。X a(r++);

  1. インクリメントrする前に参照解除可能でしたが、参照解除されなかったとします。a参照解除可能である必要がありますか?もしそうなら、そうでない場合X a(r++); *a = t;と同じ割り当てを実行する必要*r++ = t;がありますか?とに(他の)条件はaありrますか?

  2. それ以外の場合は、rインクリメントする前に参照解除/割り当てが行われ、そのインクリメントされた値は(また)参照解除可能であると想定します。次のうちどれが(もしあれば)明確に定義されています:(a) *a = t;、(b)++a; *a = t;、(c)*r = t;


フォローアップも参照してください:二重にインクリメントされたOutputIteratorへの間接参照-割り当て

4

1 に答える 1

4

お気づきのように、r++操作的意味論があります

X operator++(int) { X tmp = r; ++r; return tmp; }

X24.2.2:2によるとがIterator満たされるため、戻り値を追加しました。したがって、の戻り値を型のインスタンスにCopyConstructibleコピーコンストラクトすることは正当です。r++X

次に、*r++ = o有効である必要があります。これは、上記の操作的意味論の定義の後に{ const X &a(r++); *a = o; }シーケンスポイントとマージされるシーケンスポイントの追加のみが異なるため、複合ステートメントは式ステートメントと同じ有効性を持ちます。を呼び出すことにより、同じ有効性と操作的意味論があります。return tmp;CopyConstructible{ X a(r++); *a = o; }

その場合

*r = o;
X a(r++);

次のホールド:

  • (a)*a = oイテレータの値がすでに間接参照割り当てされているため、無効です。

  • (b)++a; *a = oイテレータの値はすでにインクリメントされており、シングルパス要件に違反しているため無効です。rインクリメント可能である必要があるのは(の新しい値)のみであるためです。24.2.4:2の注記によると、出力のアルゴリズムこのコンテキストでのパススルーの意味は指定されていませんが、イテレータは同じイテレータを2回通過しようとしないでください。

  • (c)は有効です。これは、全体と*r = oの唯一の違いは、の元の値のコピーが継続して存在することであり、要件ごとに、コピー元の値に意味的な影響を与えないためです。*r = o; r++; *r = orCopyConstructible

もう1つの興味深い質問は、(間接参照が割り当てられていない場合r)です。

X a(r);
++r;
++r;
*a = o;

これは標準で直接カバーされていませんが、それからCopyConstructibleは有効であるはずです。

于 2012-08-09T13:53:25.427 に答える