2009-12-23 82 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

是的,但這可能會導致比必要的更多的複製。我寧願一個測試重疊的函數,然後使用正確的複製技術來完成它。 –