2009-12-23 43 views
20

将数据从一个范围复制到另一个范围时,如果源范围和目标范围之间存在部分重叠,则必须小心。如果目标范围的开始与源范围的尾部重叠,则普通的顺序复制会混淆数据。除了memcpy之外,C运行时库还有memmove来处理这种重叠问题。是否std :: copy处理重叠范围?

我假设std::copy的工作方式与memcpy相似,因为它不考虑源地区和目的地区域之间的重叠。如果您尝试使用std::copystd::vector中的对象“向下”移动,则会损坏数据。是否有一个STL算法模拟memmove来处理这种情况?或者我应该用反向迭代器推出自己的产品?

回答

17

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

幸运的是,可以使用std::copy_backward代替(这要求你不重叠端与所述输入范围的输出范围的)。

+0

'std :: copy_backward'在试图实现和模拟'memmove'时很有用。我想要检查来电者的重叠负担。 –

9

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

  • 原型

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

    • [first, last)是一个有效的范围内。
    • 结果不是[first, last)范围内的迭代器。
    • 有足够的空间来容纳所有正在复制的元素。更多 正式,要求是 [result, result + (last - first))是一个 有效范围。 [1]
+0

这回答标题中的问题。剩下的问题是,是否有一种“memmove”的模拟方法,或者我是否需要推出自己的方案。 –

+3

仅禁止与目的地范围的开始重叠。正如John所说的,允许与中间或末尾重叠,并且'std :: copy_backward'允许与开始重叠(但不是结束)。 –

0

这似乎是最直接的方式是创建要复制的范围内的临时矢量:

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

您可以在模板函数,应该是巧妙地做一个重叠使用这个包起来任何容器/迭代器类型。

+2

是的,但这可能会导致比必要的更多的复制。我宁愿一个测试重叠的函数,然后使用正确的复制技术来完成它。 –