在我的代码中,我有以下内容:
ostream_iterator<double> doubleWriter(cout, " ~ ");
// ...
*doubleWriter = 1.1;
doubleWriter++;
*doubleWriter = 2.2;
*doubleWriter = 3.3; // shouldn't 2.2 be overwritten?
doubleWriter++;
*doubleWriter = 44.2;
cout << endl << endl;
我希望它能输出:
1.1 ~ 3.3 ~ 44.2 ~
相反,输出是这样的:
1.1 ~ 2.2 ~ 3.3 ~ 44.2 ~
为什么会这样?在我看来,我会覆盖2.2并在其位置坚持3.3,因为我没有增加。增量是一个可选步骤吗?
答案 0 :(得分:3)
ostream_iterator是一个输出迭代器 http://www.sgi.com/tech/stl/OutputIterator.html
输出迭代器的一个要求是在使用++运算符(pre或post)的流的每个赋值之间。因此,在不增加迭代器的情况下连续两次分配给流是未定义的行为。
Dereference assignment: *x = t
Pre-Conditions: x is dereferenceable:
If there has been a previous assignment through x,
then there has been an intervening increment.
从技术上讲,你上面所做的是未定义的行为 因此,允许实现提供您描述的输出。
请参阅de-re assignament(前置条件)的表达式语义也参见上面链接页面中的注释[3]。
官方标准报价:
http://www.open-std.org/Jtc1/sc22/wg21/docs/papers/2010/n3090.pdf(最新草稿)
第24.2.4节:第2段(由我强调)
[注意:运算符*的唯一有效用法位于赋值语句的左侧。 分配 通过迭代器的相同值只发生一次。输出迭代器的算法永远不应该 尝试两次通过相同的迭代器。它们应该是单通道算法。平等和 不平等可能没有定义。采用输出迭代器的算法可以与ostreams一起使用 通过ostream_iterator类以及插入迭代器和插入来放置数据的目标 指针。 - 后注]
我不同意AndreyT对缺陷报告485的解释:
a)输出迭代器的每个值都写入:标准允许:++ x; ++ X; ++ X;
b)输出迭代器的赋值按X a(x)的顺序进行; ++一个; * A = 1; * X = 2;是允许的 c)输出迭代器的链不能构造:X a(x); ++一个; X b(a); ++ B; X c(b); ++℃;是允许的,并且根据目前的措辞(我相信)x,a,b,c可以按任何顺序写入。
问题(a)和(c)无关 问题(b)指的是涉及多个迭代器的情况。
注意(b)我们使用迭代器a(x的副本)和迭代器x。缺点是当前标准不要求'x'在使用前增加;在'a'被分配之后。在这种情况下,情况并非如此。
答案 1 :(得分:3)
对于标准ostream_iterator
,运算符++
(前缀和后缀)都是无操作。它没有任何作用,没有任何区别。
没有必要手动执行++
,因为迭代器在输出内容时总是“前进”。
P.S。根据库Defect Report 485,目的是要求分配和增量交替。这个要求显然没有成为当前版本的标准。但在未来的修订中,它将被包括在内。换句话说,正如其他人已经指出的那样,使用输出迭代器的正确方法是交替分配和增量。
答案 2 :(得分:0)
ostream迭代器的行为是始终移动输出位置。这就是你通常想要的。