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

标签 c++ vector stl copy

Herb 提出了一种遍历 vector 的方法:

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递增。递增 result ( std::ostream_iterator ) 没有效果,递增 first将移动到 vector 中的下一个元素。然后在下一次迭代中,下一个元素被插入到 std::cout 中。再次等等。

如您所见,std::ostream_iterator并没有真正按照您期望的典型迭代器的行为方式行事(遍历一系列元素,在这些元素上执行间接操作会为您提供当前元素)。但是,它确实满足 OutputIterator 的要求因此可以作为一个使用。


这是 std::ostream_iterator::operator= 的实现来自 libstdc++:

/// 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/

相关文章:

c++ - 在 3D 空间中表示节点的最佳数据结构是什么?

c++ - 我应该在我的类中的 std::vector 成员变量中使用 std::unique_ptr<T> 吗?

c++ - 'int' 之前应为不合格 ID

c++ - 基于函数而不是集合的二进制搜索或迭代器?

c++ - 有没有比 vector< vector< T>> 更自然的方式来表示 T 的矩阵?

c++ - 返回字符串 vector

vector - Rust中的Vec <(i64,i64)>数据类型是什么?

c++ - 如何将 std::string 转换为 QString

c++ - 不能在 C++20 中将 std::cin 与 char* 或 char[] 一起使用

c++ - 左值在使用 std::map 时指定 const 对象