Herb提供了一种遍历向量的方法:
for(vector<int>::iterator i = v.begin(); i < v.end(); i++) {
cout << *i << endl;
}
他将此代码替换为:
copy(v.begin(), v.end(), ostream_iterator<int>(cout, "\n"));
我正在努力了解其工作原理或原因。我查看了复制功能,文档说它等同于:
template<class InputIterator, class OutputIterator>
OutputIterator copy (InputIterator first, InputIterator last,
OutputIterator result)
{
while (first!=last) {
*result = *first;
++result; ++first;
}
return result;
}
所以我提出了一个问题:“当我们使用OutputIterator时会发生什么?”
reference operator*() const;
Dereference iterator
Returns *this.
那就是我感到困惑的地方。我没有看到OutputIterator指向的定义。此外,我看不到行
*result = *first;
如何转换为调用cout << *i;
最佳答案
您只查询了OutputIterator
的功能。 OutputIterator
只是标准库中一堆类型满足的一组要求。这些类型之一是std::ostream_iterator
,因此您需要查看它在std::copy
上下文中的行为。
因此,在复制算法中,我们正在执行*result = *first
。首先,operator*
的std::ostream_iterator
不执行任何操作-它仅返回迭代器本身。当我们分配给该迭代器时,魔术就发生了。如果查找std::ostream_iterator::operator=
,将会看到分配给该迭代器的对象将(使用<<
)插入到其构造流中。因此,您的情况下的分配将流到std::cout
。
此后,result
和first
都增加。递增result
(std::ostream_iterator
)不起作用,递增first
将移动到向量中的下一个元素。然后在下一次迭代中,将下一个元素再次插入std::cout
中,依此类推。
正如您所看到的,std::ostream_iterator
的行为并不像典型的迭代器那样(在一系列元素之间进行间接操作会为您提供当前元素)。但是,它确实满足OutputIterator
的要求,因此可以用作一个。
这是libstdc ++中std::ostream_iterator::operator=
的实现:
/// Writes @a value to underlying ostream using operator<<. If
/// constructed with delimiter string, writes delimiter to ostream.
ostream_iterator&
operator=(const _Tp& __value)
{
__glibcxx_requires_cond(_M_stream != 0,
_M_message(__gnu_debug::__msg_output_ostream)
._M_iterator(*this));
*_M_stream << __value;
if (_M_string) *_M_stream << _M_string;
return *this;
}
忽略第一行的断言,我们可以看到它随后将
__value
插入其内部_M_stream
流中。然后,如果有一个定界符集_M_string
,它也将插入到_M_stream
中。然后返回。关于c++ - 如何使用Exception C++第1章第1部分中的copy()算法?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21903477/