2010-07-08 30 views
17

Tài liệu dành cho số tăng specialized iterator adaptors nêu rõ rằng boost::reverse_iterator "Khắc phục nhiều thiếu sót của tiêu chuẩn C++ 98 std :: reverse_iterator."Những thiếu sót của std :: reverse_iterator là gì?

Những thiếu sót này là gì? Tôi không thể tìm thấy một mô tả về những thiếu sót này.

THEO-UP HỎI:

Làm thế nào để đẩy mạnh :: reverse_iterator sửa chữa những thiếu sót?

+1

Nó thường là một chút ..... sớm. –

+0

Đăng làm nhận xét vì tôi đoán là: Triển khai sớm 'std :: reverse_iterator <>' đôi khi có lỗi. Boost có thể đơn giản là cố gắng chống lại tình huống đó. Có lẽ nhận xét là nhiều hơn về thiếu sót trong việc thực hiện 'reverse_iterator' hơn là thiếu sót trong tiêu chuẩn? –

Trả lời

10

Vâng, vấn đề lớn là họ không chuyển tiếp vòng lặp, và có những thứ mà nhiều người mong đợi các trình vòng lặp chuyển tiếp. Vì vậy, bạn phải thực hiện một số chuyển đổi vui nhộn để làm việc. Để đặt tên một số sự cố

  1. Một số phiên bản erase()insert() yêu cầu trình lặp thay vì trình lặp ngược. Điều đó có nghĩa là nếu bạn đang sử dụng một trình lặp ngược lại và bạn muốn insert() hoặc erase(), bạn sẽ phải sử dụng chức năng base() của trình lặp ngược để có được bàn tay của bạn trên một trình lặp chuyển tiếp. Không có chuyển đổi tự động.

  2. base() trả về trình tương tự chuyển tiếp tương đương với trình lặp ngược ngược về mặt chèn. Nghĩa là chèn chèn vào trước phần tử hiện tại. Yếu tố mà trình lặp ngược lại đang trỏ vào, do đó, sẽ là phần tử sai được trỏ đến nếu base() cung cấp cho bạn một trình lặp mà chỉ vào cùng một phần tử. Vì vậy, nó chỉ một chuyển tiếp, và bạn có thể sử dụng nó để chèn.

  3. Bởi vì base() trả về một trình vòng lặp trỏ vào một phần tử khác, đó là yếu tố sai để sử dụng cho erase(). Nếu bạn gọi erase() trên trình vòng lặp từ base(), bạn sẽ xóa một phần tử chuyển tiếp trong vùng chứa từ phần tử mà trình vòng lặp ngược trỏ tới, vì vậy bạn phải tăng trình lặp ngược trước khi gọi base() để nhận trình chuyển tiếp chính xác tới sử dụng cho erase().

  4. Cho dù bạn thậm chí có thể sử dụng base() với erase() để xóa chính xác một yếu tố hoàn toàn phụ thuộc vào việc triển khai của bạn hay không. Nó hoạt động với gcc, nhưng với Visual Studio họ đang thực sự chỉ gói một iterator chuyển tiếp theo cách mà làm cho nó để nó không hoạt động để sử dụng erase() khi giao dịch với iterator đảo ngược và Visual Studio. Tôi không nhớ liệu insert() có cùng một vấn đề hay không, nhưng trình lặp ngược lại không làm việc giống nhau giữa các triển khai khác nhau của C++ (theo các Visual Studio, tiêu chuẩn không đủ rõ ràng), vì vậy nó có thể là loại lông để sử dụng chúng cho bất kỳ thứ gì khác ngoài việc lặp lại đơn giản trên một vùng chứa.

Có những vấn đề có thể khác là tốt, nhưng đối phó với bất kỳ loại iterator khác hơn là một tổ chức phi const, mong lặp trong C++ khi làm bất cứ điều gì khác hơn là chỉ đơn giản lặp lại trên một container có thể nhận được một chút lông - nếu bạn thậm chí có thể làm tất cả - bởi vì rất nhiều chức năng yêu cầu các biến lặp không phải là const thay vì bất kỳ loại vòng lặp nào khác.

Nếu bạn thực sự muốn biết sự khác biệt giữa các loại trình lặp khác nhau và các vấn đề liên quan đến chúng, tôi khuyên bạn nên đọc số Hiệu quả STL của Scott Meyer. Nó có một chương tuyệt vời về vòng lặp.

EDIT: Đối với cách trình lặp ngược của Boost sửa chữa những thiếu sót đó, tôi sợ rằng tôi không có đầu mối. Tôi nhận thức được một số thiếu sót của trình lặp ngược tiêu chuẩn và đã bị chúng cắn trong quá khứ, nhưng tôi chưa bao giờ sử dụng Boost nhiều, vì vậy tôi không quen thuộc với các trình lặp ngược của chúng. Lấy làm tiếc.

+1

Tôi không chắc chắn tôi sẽ thấy những gì bạn đang nhận được. Mã mà "mong đợi" iterators chuyển tiếp không nên "thông báo" bất kỳ sự khác biệt, trừ khi họ làm những việc với hành vi không xác định ... – Cogwheel

+1

Mẫu 'std :: reverse_iterator' trong C++ 03 cho thấy cùng một danh mục của trình lặp như là trình lặp cơ bản ít nhất phải là một trình lặp vòng hai hướng, vì vậy một trình đảo ngược luôn luôn là ít nhất một trình biến đổi bi-di (và do đó một trình vòng lặp chuyển tiếp). –

+1

Tôi không tin rằng bạn đã chính xác ở đây. Tôi tin rằng một reverse_iterator là, thực sự, một iterator chuyển tiếp. Ít nhất tôi không thấy nó vi phạm khái niệm đó ở đâu. –

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