[英]C++ OutputIterator post-increment requirements
C ++要求OutputIterator类型X
支持r++
形式的表达式,其中r
是X
的实例。 此后缀增量必须在语义上等效于:
(*) { X tmp = r; ++r; return tmp; }
{ X tmp = r; ++r; return tmp; }
并且必须返回一个可转换为X const&
。 在C ++ 11中,请参见24.2.4(但这不是新的)。 它说,在同一部分
输出迭代器上的算法绝不应该尝试两次通过相同的迭代器。 它们应该是单通道算法。
给定(*),上面,假设我复制了返回值,如X a(r++);
假设r
在递增之前是不可解除的,但是没有被解除引用。 它是要求a
是dereferencable? 如果是这样,必须X a(r++); *a = t;
X a(r++); *a = t;
执行与*r++ = t;
相同的赋值*r++ = t;
否则呢? a
和r
上是否有(其他)条件?
否则,假设r
在递增之前被解除引用/分配,并且其递增的值(也)是不可引用的。 以下哪一项(如果有的话)定义明确:(a) *a = t;
,(b) ++a; *a = t;
++a; *a = t;
,(c) *r = t;
?
另请参阅后续内容: 取消引用 - 分配给双倍增量的OutputIterator
如您所知, r++
具有操作语义
X operator++(int) { X tmp = r; ++r; return tmp; }
我已经将返回值添加为X
因为每24.2.2:2 Iterator
满足CopyConstructible
,所以将r++
的返回值复制到X
类型的实例是合法的。
接下来, *r++ = o
必须有效; 这与{ const X &a(r++); *a = o; }
{ const X &a(r++); *a = o; }
{ const X &a(r++); *a = o; }
仅在另外的序列点,其与后序点汇合的return tmp;
在上面的操作语义定义中,复合语句与表达式语句具有相同的有效性。 通过调用CopyConstructible
, { X a(r++); *a = o; }
{ X a(r++); *a = o; }
{ X a(r++); *a = o; }
具有相同的有效性和操作语义。
在这种情况下
*r = o;
X a(r++);
以下举行:
(a) *a = o
无效,因为迭代器的值已被取消引用;
(b) ++a; *a = o
++a; *a = o
无效,因为迭代器的值已经增加,违反了单遍要求,因为只需要(新值) r
可递增:根据24.2.4的注释:2, 算法输出迭代器永远不应该尝试两次通过相同的迭代器 ,尽管它没有指定在此上下文中传递的方法;
(c) *r = o
有效,因为*r = o; r++; *r = o
的唯一区别*r = o; r++; *r = o
*r = o; r++; *r = o
*r = o; r++; *r = o
总是原始值的一个拷贝的继续存在r
其中每CopyConstructible
要求对从复制的值没有语义效果。
另一个有趣的问题是(对于非解除引用的r
):
X a(r);
++r;
++r;
*a = o;
标准不直接涵盖这一点,但从CopyConstructible
,它应该是有效的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.