2012-05-14 38 views
10

Về việc sử dụng thực tế những gì khác biệt là có giữacopy_backward hoặc sao chép với reverse_iterators?

a) copy_backward

b) sao chép với reverse_iterators cho nguồn và đích

Đặc biệt là một cách tổng quát hơn được áp dụng hơn khác không? Có sự khác biệt nào khác không?

Cập nhật: Nếu thực sự không có sự khác biệt, thì bất kỳ tham chiếu nào trong tài liệu C++ cho sự tương đương này đều được đánh giá cao. Động lực đằng sau câu hỏi này là để hiểu nếu điều này là do thiết kế hoặc một trong những bản tóm tắt đó (như thiếu copy_if)

+0

Tôi sẽ không ngạc nhiên nếu, trên thực tế, sử dụng 'reverse_iterator' yêu cầu loại trình lặp được gắn thẻ đúng trong khi' copy_backward' được triển khai như một vòng lặp đơn giản. Rõ ràng là điều đó không được đảm bảo. Theo như tiêu chuẩn có liên quan, tất cả các trình vòng lặp phải được gắn thẻ. –

+0

hmm ... dọc theo cùng một dòng có thể reverse_iterator có lẽ chậm hơn trong trường hợp iterator ban đầu là một T *? – hawk

+0

'T *' được gắn thẻ như một trình vòng lặp truy cập ngẫu nhiên, vì có một chuyên môn được đảm bảo một phần 'mẫu struct iterator_traits ;'. –

Trả lời

-1

Không có sự khác biệt nào về mặt thực tế. Theo cách tương tự, bạn có thể so sánh việc sao chép chuyển tiếp.

a) sao chép

b) copy_backward với trình lặp lại ngược.

+1

Đó là về mặt kỹ thuật không đúng vì bản sao tổng quát hơn ở chỗ nó có thể được sử dụng với các trình lặp đầu vào/đầu ra. Nó không yêu cầu trình vòng lặp hai chiều. – hawk

+1

Vì vậy, bạn đã trả lời câu hỏi của mình =) Có sự khác biệt về mặt kỹ thuật. – inkooboo

+2

@inkooboo: đó là sự khác biệt giữa (a) và (b) của bạn: một yêu cầu ít nhất một trình lặp hai chiều, và cái kia thì không. Sự khác biệt tương tự cũng không áp dụng cho diều hâu (a) và (b), vì cả hai đều yêu cầu ít nhất một trình lặp hai chiều. –

-1

Không có bất kỳ sự khác biệt nào, tuy nhiên: copy_backward có ích trong trường hợp trình lặp là kết quả của một số cuộc gọi hàm và cũng sạch hơn nhiều so với việc sử dụng bản sao với trình lặp ngược.

5

Trước hết, việc sử dụng copy_backward() rõ ràng cho thấy ý định của nhà phát triển là sao chép khoảng thời gian theo thứ tự ngược lại.

copy_backward() hoạt động với các trình vòng lặp hai chiều ban đầu, trong khi trình đảo chiều là bộ điều hợp của trình lặp hai chiều và có thể không hiệu quả như trình lặp ban đầu.

Sử dụng trình reverse_iterator có ý nghĩa khi bạn cần áp dụng thuật toán cho các trình vòng lặp đầu vào như copy() để đảo ngược chuỗi, nhưng không có đối tác cho các toán tử hai chiều như copy_backward().

Do đó, có khác biệt thực tế khái niệm.

0

Sự khác biệt là copy trả về một iterator đến phần tử pass-the-end trong khi copy_backward trả về một iterator cho phần tử đầu tiên.

Chúng không tương đương với ý nghĩa đó.

  • Chữ ký tất nhiên khác nhau. copy là ok với InputIterator s và OutputIterator. Trong khi copy_backward mong đợi BidirectionalIterator s.
  • Hiệu ứng trên vùng chứa (khi được sử dụng chính xác) là giống nhau, nhưng các trình vòng lặp được trả về có các loại khác nhau và trỏ đến các phần tử khác nhau.

Ví dụ:

này hoạt động vì vector có thể sử dụng RandomAccessIterator mà không hỗ trợ các tính chất mong đợi bởi InputIterator, OutputIteratorBidirectionalIterator.

#include <iostream> 
#include <algorithm> 
#include <vector> 
using namespace std; 

void printer(int i) { 
    cout << i << ", "; 
} 

int main() { 

    int mynumbers[] = {3, 9, 0, 2, 1, 4, 5}; 
    vector<int> v1(mynumbers, mynumbers + 7); 

    vector<int>::iterator it = copy_backward(mynumbers, mynumbers + 7, v1.end()); 
    for_each(v1.begin(), v1.end(), printer); 
    cout << endl << "Returned element: " << *it; 
    cout << endl; 

    vector<int>::reverse_iterator rit = copy(mynumbers, mynumbers + 7, v1.rbegin()); 
    for_each(v1.begin(), v1.end(), printer); 
    cout << endl << "Before the first element (reverse end)? " << (rit == v1.rend()); 
    rit--; // go to first element, because it is a reverse iterator 
    cout << endl << "Returned element: " << *rit; 

    return 0; 
} 

Kết quả:

3, 9, 0, 2, 1, 4, 5, 
Returned element: 3 
5, 4, 1, 2, 0, 9, 3, 
Before the first element (reverse end)? 1 
Returned element: 5 

Nếu bạn muốn sử dụng một container mà không hỗ trợ BidirectionalIterator sau đó bạn có nguy cơ gặp rắc rối (ví dụ nếu bạn muốn cố gắng sao chép ngược một forward_list vì nó sử dụng một ForwardIterator, không hỗ trợ các hoạt động được cung cấp bởi BidirectionalIterator).
Cũng trong trường hợp này sao chép với trình lặp ngược trên forward_list cũng không thể thực hiện được, vì nó không hỗ trợ trình lặp ngược.

Về cơ bản, bạn cần phải đảm bảo trình vòng lặp của vùng chứa được hỗ trợ và chọn theo phần cuối của vùng chứa bạn muốn trả lại. Nếu không thì hiệu ứng là như nhau.

Các vấn đề liên quan