2009-06-30 54 views
7

Tôi đã viết mẫu vùng chứa của riêng mình với một trình lặp. Làm cách nào để triển khai const_iterator?C++: Làm thế nào để viết một const_iterator?

template <class T> 
class my_container { 
private: 
    ... 

public: 
    my_container() : ... { } 
    ~my_container() { } 

    class iterator : public std::iterator<std::bidirectional_iterator_tag, T> { 
    public: ... 

Trả lời

4

Sự khác biệt duy nhất là khi bạn không tham chiếu đến trình biến đổi const bạn nhận tham chiếu const thay vì tham chiếu đến đối tượng trong vùng chứa.

+1

Điều gì về các phương thức lấy biến lặp làm đối số hoặc trả về trình lặp? Tôi phải quá tải chúng cho const_iterators? Có vẻ như một loạt các mã lặp đi lặp lại. –

+0

trình lặp nên được chuyển đổi thành const_iterators, vì vậy bạn sẽ không phải quá tải nếu bạn chỉ cần một const_iterator. Bạn làm cho các hàm như begin(), end(), nhưng không có cách nào xung quanh, vì const cũng là một phần của chữ ký của phương thức. –

+2

@ Posco Grubb: Không. Nếu bạn có các phương thức lấy các trình vòng lặp thì các khuôn mẫu của chúng. Phương thức này sẽ làm việc cho bất kỳ thứ gì hoạt động như một trình lặp. Nếu phương thức yêu cầu một trình lặp (iterator) hơn là một trình soạn thảo const_iterator, trình biên dịch sẽ tạo ra lỗi thích hợp. –

2

Tôi tìm cách dễ nhất để triển khai trình lặp là boost::iterator. Nếu bạn muốn cuộn của riêng bạn, tôi nghĩ rằng chữ ký nên là:

class const_iterator : public std::iterator<std::bidirectional_iterator_tag, const T> { 

với việc thực hiện như nhau (giả sử bạn đang sử dụng reference_type và vân vân trong chữ ký chức năng của bạn)

+0

Tôi đã ngạc nhiên khi thấy rằng iterator_traits :: const_iterator> :: value_type là int, không int const (T, thay vì const T trong mã của bạn). Tôi nghĩ rằng với const có ý nghĩa hơn mặc dù. Tuy nhiên, dòng dưới cùng là nếu bạn muốn kết hợp với các thùng chứa chuẩn, bạn cần sử dụng non-const T. –

+0

Điều quan trọng với trình lặp const là bạn không thể sử dụng nó để thay đổi bộ sưu tập đang được lặp lại. Vì vậy, T hoặc const T & là thích hợp. Sử dụng const với chỉ T là không cần thiết (vì sự trở lại sẽ là một bản sao) –

+0

Vâng, nếu bạn muốn xác định rằng by-value là non-const, bạn phải chỉ định tất cả các tham số: class const_iterator: public std :: trình lặp . Tôi sẽ đi với ngắn gọn (với một số bảo vệ thêm chống lại các lỗi gán/bình đẳng) hơn là phù hợp với vector STL, nhưng nó là một sự lựa chọn khó khăn từ một quan điểm thiết kế. –

0

Roger Pate, value_types là "đơn giản". Tôi nghi ngờ bạn sẽ thấy const nếu bạn nhìn vào iterator_traits :: const_iterator> :: reference, mà tôi nghĩ rằng sẽ là "const int &".

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