STL复制实现

时间:2011-12-07 22:34:21

标签: stl iterator copy

根据http://www.sgi.com/tech/stl/copy.html,以下是副本的定义。

template<class InputIterator, class OutputIterator>
  OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result)
{
   while (first != last) *result++ = *first++;
   return result;
}

我写了以下代码。

vector<int> v;
set<int> s;

s.insert(7);
s.insert(11);
s.insert(27);

//copy elements from the set into the vector
copy(s.begin(), s.end(), v.begin());

为什么上面的复制调用会产生运行时错误但不会产生编译错误?我假设它与向量为空的事实有关,v.begin()== v.end()。但为什么呢?

此外,我通过将代码更改为以下来修复代码。

copy(s.begin(), s.end(), back_inserter(v));

函数back_inserter返回类型为back_insert_iterator&gt;的迭代器。为什么这样做?它在做什么?

2 个答案:

答案 0 :(得分:2)

它失败了,因为你不尊重同一网站上列出的第三个前提条件:

  

有足够的空间来容纳所有被复制的元素。更多   正式地,要求是[结果,结果+(最后 - 第一))是   有效范围。 [1]

空向量小于一组3个元素,因此您无法执行复制操作(实际上应该称为“覆盖”操作)。这些信息在编译时是未知的,因此没有编译时失败。请记住,虽然向量和大多数其他C ++ STL集合在运行时是可扩展的,但它们无法通过常规迭代器操作进行扩展(这些操作主要用于枚举项目和指定范围)。

back_inserter函数返回一个特殊的迭代器,它将元素插入到集合的末尾。这个迭代器是一个输出迭代器,与你可以通过向量的begin()end()方法获得的迭代器几乎没有关系。你无法从输出迭代器中读取。

答案 1 :(得分:0)

想想数组的简单情况 - 带有迭代器的指针。现在,假设s和v是数组。如果s有3个元素并且v 0并且你试图将s复制到v中它将不起作用。但是,如果v有3个元素,则副本可以工作,覆盖当前内容。

STL中的迭代器模型是对此的概括。实际上,指针可以用作迭代器,但其他对象也可以使用(你可以使用指向数组第一个元素的指针调用copy,并使用指向结尾的指针调用back_inserter)。因此,它不能用于完全相同的原因。

{{1}}是一个迭代器,仅适用于这种情况;而不是通过集合覆盖其当前位置,它增加了集合的大小(当然必须是可以增长的集合,例如向量)并写入新的位置。