C++ OutputIterator post-increment requirements

Deadly 提交于 2019-12-04 02:39:38

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!