2009-12-23 10 views
20

Khi sao chép dữ liệu từ một phạm vi này sang phạm vi khác, bạn phải cẩn thận nếu có chồng chéo một phần giữa phạm vi nguồn và đích. Nếu phần đầu của phạm vi đích trùng lặp đuôi của phạm vi nguồn, một bản sao tuần tự đơn giản sẽ thu thập dữ liệu. Thư viện thời gian chạy C có memmove ngoài memcpy để xử lý các vấn đề trùng lặp đó.Có std :: copy xử lý các phạm vi chồng chéo?

Tôi giả định std::copy hoạt động như memcpy, ở chỗ nó không trả bất kỳ liên quan đến chồng chéo giữa vùng nguồn và đích. Nếu bạn cố gắng chuyển các đối tượng "xuống" trong một số std::vector với std::copy, bạn sẽ làm hỏng dữ liệu. Có một thuật toán tương tự STL của memmove để xử lý các tình huống như thế này không? Hoặc tôi nên cuộn của riêng tôi với iterators ngược?

Trả lời

17

Nó không xử lý chồng chéo dãy iff bắt đầu của dãy đầu ra trùng với phạm vi đầu vào.

May mắn thay, bạn có thể sử dụng std::copy_backward thay vì (mà đòi hỏi bạn phải không chồng lên cuối của dãy đầu ra với phạm vi đầu vào).

+0

'std :: copy_backward' sẽ hữu ích khi cố gắng triển khai và tương tự' memmove'. Tôi muốn kiểm tra gánh nặng chồng lên nhau của người gọi. –

9

điều kiện tiên quyết cho std::copy, cấm sự chồng chéo:

  • Prototype

    template <class InputIterator, class OutputIterator> 
    OutputIterator copy(InputIterator first, InputIterator last, 
            OutputIterator result); 
    
  • điều kiện tiên quyết

    • [first, last) là một phạm vi hợp lệ.
    • kết quả không phải là một trình lặp trong phạm vi [first, last).
    • Có đủ không gian để giữ tất cả các phần tử được sao chép. Thêm chính thức, yêu cầu là [result, result + (last - first)) là một phạm vi hợp lệ . [1]
+0

Điều đó trả lời câu hỏi trong tiêu đề. Câu hỏi còn lại là liệu có một sự tương tự của 'memmove' hoặc nếu tôi phải cuộn của riêng tôi. –

+3

Điều đó chỉ cấm trùng lặp khi bắt đầu phạm vi đích. Như John nói, một chồng chéo với giữa hoặc kết thúc được cho phép, và 'std :: copy_backward' cho phép chồng chéo với sự bắt đầu (nhưng không phải là kết thúc). –

0

Có vẻ như con đường thẳng nhất về phía trước sẽ tạo ra một vector tạm thời của dãy núi này bạn muốn sao chép:

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

Bạn có thể quấn này trong một chức năng templated rằng nên ably để làm một chồng chéo sử dụng bất kỳ loại container/iterator nào.

+2

Vâng, nhưng điều đó có thể dẫn đến việc sao chép nhiều hơn mức cần thiết. Tôi muốn đúng một chức năng mà kiểm tra cho chồng lên nhau và sau đó sử dụng kỹ thuật sao chép phù hợp để làm điều đó tại chỗ. –