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

此后,resultfirst都增加。递增resultstd::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/

10-11 22:09
查看更多