C ++ OutputIterator后增量要求

时间:2012-08-09 02:52:38

标签: c++ iterator post-increment

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

(*){ 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;相同的分配吗? ar上是否有(其他)条件?

  2. 否则,假设r在递增之前被解除引用/分配,并且其递增的值(也)是不可引用的。下列哪一项(如果有的话)定义明确:(a) *a = t;,(b)++a; *a = t;,(c)*r = t;


  3. 另请参阅后续行动:Dereference-assignment to a doubly incremented OutputIterator

1 个答案:

答案 0 :(得分:4)

如您所知,r++具有操作语义

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

我已将返回值添加为X因为每24.2.2:2 Iterator满足CopyConstructible,因此复制构造{{1}的返回值是合法的进入r++类型的实例。

接下来,X必须有效;这与*r++ = o的区别仅在于添加了一个序列点,该序列点与上面操作语义定义中{ const X &a(r++); *a = o; }之后的序列点合并,因此复合语句具有相同的作为表达陈述的有效性。通过调用return tmp;CopyConstructible具有相同的有效性和操作语义。

在案件中

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

以下举行:

  • (a)*r = o; X a(r++); 无效,因为迭代器的值已被取消引用分配;

  • (b)*a = o无效,因为迭代器的值已经增加,违反了单遍要求,因为只需要(新值)++a; *a = o可递增的:根据24.2.4:2的注释,输出迭代器上的算法永远不应该 尝试两次通过相同的迭代器,虽然未指定传递在此上下文中的含义;

  • (c)r有效,因为*r = o总体上唯一的区别是*r = o; r++; *r = o的原始值的副本仍然存在,每r { 1}}要求对从。

  • 复制的值没有语义影响

另一个有趣的问题是(对于非解除引用的CopyConstructible):

r

标准不直接涵盖此标准,但从X a(r); ++r; ++r; *a = o; 开始它似乎有效。