2013-02-27 70 views
5

Tôi đang viết một iterator (trên thực tế nó là const_iterator cho đối tượng hiện tại của tôi, và tôi cũng muốn tạo một reverse_const_iterator cũng có.C++ iterator và đảo ngược iterator

Tôi nhìn xung quanh, để xem làm thế nào để làm điều này và tôi tình cờ this:.

Thông báo tuy nhiên rằng khi một iterator được đảo ngược, phiên bản đảo ngược không trỏ đến cùng một nguyên tố trong phạm vi, nhưng đến một trước nó này là như vậy, để sắp xếp cho phần tử cuối cùng của một phạm vi: An it erator trỏ đến một phần tử cuối cùng trong một phạm vi, khi đảo ngược, được thay đổi để trỏ đến phần tử cuối cùng (không phải qua nó) của phạm vi (đây sẽ là phần tử đầu tiên của dải nếu đảo ngược). Và nếu một iterator cho phần tử đầu tiên trong một phạm vi được đảo ngược, trình vòng lặp đảo ngược trỏ đến phần tử trước phần tử đầu tiên (đây sẽ là phần tử cuối cùng của dải nếu được đảo ngược).

Đây có phải là những gì xảy ra trong nhận thức của người dùng, hoặc khi bạn dereference một reverse_iterator làm nó không trừu tượng này đi bằng cách cho bạn giá trị/tài liệu tham khảo của đối tượng bạn nghĩ nó được trỏ đến? Đây chỉ là chi tiết triển khai?

hiểu biết của tôi là:

for(i = obj.rbegin(); i != obj.rend(); i++) 

tương đương với

for(i = obj.begin(); i != obj.end(); i++) 

trừ ngược lại. Và vì vậy *i sẽ quay ngược lại thông qua vùng chứa trong trường hợp đầu tiên và chuyển tiếp qua vùng chứa trong trường hợp thứ hai. Bản năng của tôi có đúng không?

+2

Nó chỉ hoạt động. –

+0

Lưu ý: Khi làm việc với các trình vòng lặp, bạn nên luôn sử dụng tiền tăng ('++ i') thay vì tăng sau vì nó có thể hiệu quả hơn. –

Trả lời

5

Bạn nói đúng là nó trừu tượng. Trình lặp ngược lại chứa một trình lặp bình thường trỏ vào phần tử sau đối tượng bạn sẽ nhận được nếu bạn bỏ qua nó. Tuy nhiên, nó không chỉ đơn thuần là một chi tiết thực hiện. Bộ chuyển đổi std::reverse_iterator cung cấp cuộc gọi hàm thành viên base trả về trình lặp lặp cơ bản.

Các tiêu chuẩn định nghĩa std::reverse_iterator như một adapter iterator với mối quan hệ sau vào iterator Thích ứng của nó:

Mối quan hệ cơ bản giữa một iterator đảo ngược và iterator tương ứng của nó tôi được thành lập bởi bản sắc: &*(reverse_iterator(i)) == &*(i - 1)

Sử dụng phổ biến cho base là xóa phần tử khỏi vùng chứa, sẽ được thực hiện như sau:

it++; 
lst.erase(it.base()); 

Nếu bạn muốn làm điều này trong khi iterating trên container ngược lại, bạn sẽ làm gì:

it++; 
std::list<int>::reverse_iterator(lst.erase(it.base())); 
+0

Là một câu hỏi phụ, tại sao nó sẽ hữu ích để có được 'cơ sở' bên dưới' trình lặp'? – Bingo

+0

@Bingo: vì các vùng chứa có thể mong đợi nó, ví dụ, 'erase' được chỉ định là lấy một' iterator' và * not * a 'reverse_iterator'. –

+0

@Matthieu oh, phải. Điều đó có ý nghĩa. – Bingo