【问题标题】:STL copy implementationSTL 拷贝实现
【发布时间】:2011-12-07 22:34:21
【问题描述】:

下面是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> 类型的迭代器。为什么这行得通?它在做什么?

【问题讨论】:

    标签: stl iterator copy


    【解决方案1】:

    失败是因为您没有遵守同一网站上列出的第三个前提条件:

    有足够的空间容纳所有被复制的元素。更多的 形式上,要求是 [result, result + (last - first)) 是 有效范围。 [1]

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

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

    【讨论】:

      【解决方案2】:

      想一想数组的简单例子——用指针指向它们的迭代器。现在,想象 s 和 v 是数组。如果 s 有 3 个元素和 v 0 并且您尝试将 s 复制到 v 它将不起作用。但是,如果 v 有 3 个元素,则副本将起作用,覆盖当前内容。

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

      back_inserter 是一个迭代器,专门用于这种情况;它不会在集合中移动并覆盖其当前位置,而是增加集合的大小(因此它当然必须是可以增长的集合,例如向量)并写入新位置。

      【讨论】:

        猜你喜欢
        • 2016-12-03
        • 2015-08-23
        • 2013-03-19
        • 2016-03-20
        • 2015-06-12
        • 1970-01-01
        • 2021-12-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多