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
, OutputIterator
và BidirectionalIterator
.
#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.
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ẻ. –
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
'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 ;'. –