nkn*_*ght 9 c++ iterator post-increment
C++要求OutputIterator类型X支持表单的表达式r++,其中r是一个实例X.此后缀增量必须在语义上等效于:
(*) { X tmp = r; ++r; return tmp; }
并且必须返回可转换为的类型X const&.在C++ 11中,请参见24.2.4(但这不是新的).它说,在同一部分
输出迭代器上的算法绝不应该尝试两次通过相同的迭代器.它们应该是单通道算法.
给出(*),上面说我复制返回值就像 X a(r++);
假设r在递增之前是dereferencable,但没有取消引用.它是否需要a被取消参考?如果是这样,必须X a(r++); *a = t;执行相同的任务*r++ = t;吗?是否有任何(其他)条件a和r?
否则,假设r在递增之前被解除引用/分配,并且其递增的值(也)是不可引用的.以下哪一项(如果有的话)定义明确:(a)
*a = t;,(b)++a; *a = t;,(c)*r = t;?
另请参阅后续操作:取消引用 - 分配给双倍增量的OutputIterator
正如您所注意到的,r++具有操作语义
X operator++(int) { X tmp = r; ++r; return tmp; }
Run Code Online (Sandbox Code Playgroud)
我添加了返回值,X因为 24.2.2:2Iterator满足CopyConstructible,因此将 的返回值复制构造r++到类型 的实例中是合法的X。
接下来,*r++ = o需要有效;与上面操作语义定义中的后面的序列点合并,仅{ const X &a(r++); *a = o; }增加了一个序列点,因此复合语句与表达式语句具有相同的有效性。通过调用,具有相同的有效性和操作语义。return tmp;CopyConstructible{ X a(r++); *a = o; }
在这种情况下
*r = o;
X a(r++);
Run Code Online (Sandbox Code Playgroud)
以下保留:
(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;
Run Code Online (Sandbox Code Playgroud)
标准没有直接涵盖这一点,但从CopyConstructible它看来它应该是有效的。