C++ OutputIterator post-increment requirements

后端 未结 1 2059
鱼传尺愫
鱼传尺愫 2021-02-15 06:39

C++ requires that an OutputIterator type X support expressions of the form r++, where r is an instance of X. This postfix inc

相关标签:
1条回答
  • 2021-02-15 07:08

    As you note, r++ has operational semantics

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

    I've added the return value as X because per 24.2.2:2 Iterator satisfies CopyConstructible, so it is legitimate to copy construct the return value of r++ into an instance of type X.

    Next, *r++ = o is required to be valid; this differs from { const X &a(r++); *a = o; } only in the addition of a sequence point, which merges with the sequence point after return tmp; in the operational semantics definition above, so the compound statement has the same validity as the expression statement. By invoking CopyConstructible, { X a(r++); *a = o; } has the same validity and operational semantics.

    In the case

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

    the following hold:

    • (a) *a = o is invalid because that value of the iterator has already been dereference-assigned;

    • (b) ++a; *a = o is invalid because that value of the iterator has already been incremented, violating the single-pass requirement, as only (the new value of) r is required to be incrementable: per the note to 24.2.4:2, Algorithms on output iterators should never attempt to pass through the same iterator twice, although it's not specified what pass through means in this context;

    • (c) *r = o is valid, because the only difference to *r = o; r++; *r = o overall is the continued existence of a copy of the original value of r, which per CopyConstructible requirements has no semantic effect on the value copied from.

    Another interesting question is (for a non-dereference-assigned r):

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

    This isn't covered by the standard directly, but from CopyConstructible it appears it should be valid.

    0 讨论(0)
提交回复
热议问题