代码之家  ›  专栏  ›  技术社区  ›  Adrian McCarthy

std::copy是否处理重叠范围?

  •  21
  • Adrian McCarthy  · 技术社区  · 15 年前

    将数据从一个范围复制到另一个范围时,如果源和目标范围之间存在部分重叠,则必须小心。如果目标范围的开始部分与源范围的结尾部分重叠,那么一个普通的顺序复制将混淆数据。C运行时库具有 memmove 除了 memcpy 处理这样的重叠问题。

    我假设 std::copy 作品像 曼皮西 ,因为它不考虑源区域和目标区域之间的重叠。如果您试图在 std::vector 具有 STD:复制 ,您将损坏数据。有STL算法类似于 默默斯 处理这样的情况?还是应该使用反向迭代器滚动自己的代码?

    4 回复  |  直到 6 年前
        1
  •  18
  •   John Feminella    12 年前

    它不能处理重叠的范围 开始 输出范围与输入范围重叠。

    幸运的是,您可以使用 std::copy_backward 相反(这要求您不要将 结束 输出范围和输入范围)。

        2
  •  9
  •   Flexo - Save the data dump sunny moon    13 年前

    的前提条件 std::copy ,禁止重叠:

    • 原型

      template <class InputIterator, class OutputIterator>
      OutputIterator copy(InputIterator first, InputIterator last,
                          OutputIterator result);
      
    • 先决条件

      • [first, last) 是有效范围。
      • 结果不是范围内的迭代器 [第一,最后] .
      • 有足够的空间容纳所有要复制的元素。更多 正式来说,要求是 [result, result + (last - first)) 是一个 有效范围。 [1]
        3
  •  0
  •   Doug T.    15 年前

    似乎最直接的方法是创建一个临时的向量,该向量的范围是您想要复制的:

    std::vector copiedRange( srcVecIterBegin, srcVecIterEnd);
    std::copy( copiedRange.begin(), copiedRange.end(), srcVecIterCopyLocIter);
    

    您可以将其包装在模板函数中,该函数应该能够使用任何容器/迭代器类型进行重叠。

        4
  •  0
  •   Ciro Santilli OurBigBook.com    6 年前

    C++ 17标准草案

    这个 C++17 n4659 standard draft 说:

    22.61.“复制”:

    template<class InputIterator, class OutputIterator>
    OutputIterator copy(InputIterator first, InputIterator last,
                        OutputIterator result);
    

    1要求:结果不在范围内[第一,最后]。

    2效果:将范围[第一个,最后一个]中的元素复制到范围[结果,结果+(最后一个)- 从第一个开始,一直到最后一个。

    还有:

    template<class BidirectionalIterator1, class BidirectionalIterator2>
    BidirectionalIterator2
    copy_backward(
        BidirectionalIterator1 first,
        BidirectionalIterator1 last,
        BidirectionalIterator2 result);
    

    17要求:结果不在范围内(第一个、最后一个)。

    18效果:将范围[第一个,最后一个]中的元素复制到范围[结果(最后一个,第一个)] 结果)从最后一个-1开始,一直到第一个。(263)对于每个正整数n<=(最后一个- 首先),执行*(result-n)=*(last-n)。

    然后说明何时使用 copy_backward :

    263)当last在范围内时,应使用copy-backward而不是copy[结果-(last-first),result]

    因此,这些功能不需要重叠,并且 unlike for memcpy ,重叠的行为在 Effects 部分。

    你只是在它们之间选择,因为你通常想要 std::copy 用于向左复制和 std::copy_backward 复制权利。

    C++也有一个远程版本。 std::move 在里面 <algorithm> 移动而不是复制。