9

C++ 要求 OutputIterator 类型X支持形式的表达式r++,其中r是 的实例X。这个后缀增量必须在语义上等价于:

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

并且必须返回可转换为X const&. 在 C++11 中,请参阅 24.2.4(但这并不是新的)。在同一部分,它说

输出迭代器的算法永远不应该尝试通过同一个迭代器两次。它们应该是单通道算法。

给定(*),上面说我复制返回值,如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; }

我添加了返回值,X因为 per 24.2.2:2Iterator满足CopyConstructible,因此将构造的返回值复制r++到 type 的实例中是合法的X

接下来,*r++ = o必须是有效的;这与上面的操作语义{ const X &a(r++); *a = o; }定义中仅增加了一个序列点不同,它与序列点after合并,因此复合语句与表达式语句具有相同的有效性。通过调用,具有相同的有效性和操作语义。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 的注释,输出算法迭代器永远不应该尝试通过同一个迭代器两次,尽管没有指定在这种情况下通过是什么意思;

  • (c)*r = o是有效的,因为与整体的唯一区别*r = o; r++; *r = o是 的原始值的副本的持续存在,r根据CopyConstructible要求,该副本对从中复制的值没有语义影响。

另一个有趣的问题是(对于非取消引用分配r):

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

标准没有直接涵盖这一点,但从CopyConstructible看来它应该是有效的。

于 2012-08-09T13:53:25.427 回答