即使我覆盖了STL ostream_iterator写入屏幕?

时间:2010-06-15 22:39:30

标签: c++ stl iterator

在我的代码中,我有以下内容:

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,因为我没有增加。增量是一个可选步骤吗?

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迭代器的行为是始终移动输出位置。这就是你通常想要的。