如何使用Exception C ++第1章第1部分中的copy()算法?

时间:2014-02-20 09:27:22

标签: c++ vector stl copy

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;

1 个答案:

答案 0 :(得分:5)

您只查找OutputIterator的内容。 OutputIterator只是标准库中的一堆类型满足的一组要求。其中一种类型是std::ostream_iterator,因此您需要在std::copy的上下文中查看其行为。

因此在复制算法中,我们正在进行*result = *first。首先,operator*的{​​{1}}什么都不做 - 它只返回迭代器本身。当我们分配给这个迭代器时,就会发生魔法。如果查找std::ostream_iterator::operator=,您将看到分配给此迭代器将(使用std::ostream_iterator)插入到构造它的流中。因此,您案例中的作业将流入<<

此后,std::coutresult都会增加。递增firstresult)无效,递增std::ostream_iterator将移动到向量中的下一个元素。然后在下一次迭代中,将下一个元素再次插入first,依此类推。

正如您所看到的,std::cout并不像您期望典型迭代器的行为那样(通过一系列元素移动,在这些元素上执行间接操作会为您提供当前元素)。但是,它 符合std::ostream_iterator的要求,因此可以作为一个。


以下是来自libstdc ++的OutputIterator的实现:

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。然后它返回。