在ostream_iterator
的许多例子中,我注意到在写操作之间使用了一个增量操作:
。
#include <iostream>
#include <iterator>
using namespace std;
int main() {
ostream_iterator<char> itr{ cout };
*itr = 'H';
++itr; // commenting out this line appears to yield the same output
*itr = 'i';
}
在cpp引用增量(operator++
)上被列为no-op。尽管没有手术,但有什么理由把它包括进去吗?这是"最佳实践"吗?包括?
明明可以直接打印到cout
,为什么还存在ostream_iterator
呢?
答案:用于需要迭代器的函数
要成为"迭代器",类型必须满足一系列要求。(这也是这些函数所期望的),以某种方式重载++
和*
就是其中之一。
*
和++
对ostream迭代器不做任何操作。如果你问你是否应该打电话给他们,你一开始就不需要ostream_iterator
。
考虑std::copy
的可能实现:
template<class InputIt, class OutputIt> OutputIt copy(InputIt first, InputIt last, OutputIt d_first) { for (; first != last; (void)++first, (void)++d_first) { *d_first = *first; } return d_first; }
此代码适用于所有输出迭代器。它也适用于std::ostream_iterator
。在这种情况下,++d_first
是一个noop,但它仍然必须是有效的代码,因为对于其他输出迭代器来说,它是需要的。
实际上std::ostream_iterator
存在的主要原因是为了与这种泛型算法一起使用,否则你可以直接写入流。这是一个很好的例子,迭代器是算法和容器之间的粘合剂,或者更一般地说,是数据之间的粘合剂。算法可以是泛型的,不需要关心数据的实际来源或去向,因为迭代器实现了这种特殊情况。
也来自cppreference onstd::ostream_iterator::operator++
:
什么也不做。提供这些操作符重载是为了满足LegacyOutputIterator的要求。他们使……成为可能用于输出的表达式
*iter++=value
和*++iter=value
(插入)一个值到底层流
对于你的实际问题:
是否有理由包括它,尽管它是一个无操作?这是"最佳实践"吗?包括?
。当知道它是std::ostream_iterator
时,对迭代器进行加1是没有意义的。它可以递增的唯一原因是对于泛型代码。