C++要求OutputIterator类型X
支持r++
形式的表达式,其中r
是X
的实例。此后缀增量在语义上必须等效于:
(*){ X tmp = r; ++r; return tmp; }
并且必须返回可转换为X const&
的类型。在C++ 11中,请参阅24.2.4(但是,这不是新的)。在同一部分中,它说
给定上面的(*),说我复制了X a(r++);
之类的返回值
r
在递增之前是可取消引用的,但未取消引用。是否要求a
是可取消引用的?如果是这样,X a(r++); *a = t;
是否必须执行与*r++ = t;
相同的分配? a
和r
是否有(其他)条件? r
进行了取消引用/分配,并且其递增值也是(也)可取消引用的。以下哪项(如果有的话)是定义明确的:(a)*a = t;
,(b)++a; *a = t;
,(c)*r = t;
吗? 另请参阅后续内容:Dereference-assignment to a doubly incremented 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; }
的不同仅在于增加了一个序列点,该序列点在上述操作语义定义中与return tmp;
之后的序列点合并,因此复合语句与表达式语句具有相同的有效性。通过调用CopyConstructible
,{ X a(r++); *a = o; }
具有相同的有效性和操作语义。在这种情况下
*r = o;
X a(r++);
以下内容:
*a = o
无效,因为该迭代器的值已被取消引用分配; ++a; *a = o
无效,因为迭代器的值已经增加,这违反了单遍要求,因为仅r
(的新值)要求是可递增的:根据注释,至24.2.4:2,输出迭代器上的算法永远不应该尝试两次通过同一个迭代器,尽管在这种情况下未指定通过哪种方式;
*r = o
是有效的,因为总体上与*r = o; r++; *r = o
的唯一区别是继续存在r
原始值的拷贝,根据CopyConstructible
的要求,该拷贝对从其复制的值没有语义影响。 另一个有趣的问题是(对于非取消引用分配的
r
):X a(r);
++r;
++r;
*a = o;
该标准未直接涵盖此问题,但是从
CopyConstructible
看来它应该是有效的。关于C++ OutputIterator后增要求,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11876128/