Đặc tả C++ về chính xác một vùng chứa STL là nhiệm vụ mà bất kỳ loại vùng chứa STL nào có sẵn một số trường khác nhau. Một số, như begin()
và end()
, là các hàm, trong khi các số khác, chẳng hạn như iterator
, là các loại. Những hạn chế này cũng áp dụng cho các trình vòng lặp. Điều này cho phép các hàm mẫu C++ nhìn vào các kiểu đối số của chúng để tìm kiếm nhiều thuộc tính hơn. Ví dụ, tất cả các kiểu vòng lặp STL phải định nghĩa một trường iterator_category
có chứa kiểu mã hóa khả năng của chúng. Bằng cách này, các thuật toán STL có thể có các triển khai khác nhau của các hàm khác nhau dựa trên sức mạnh của các trình vòng lặp mà chúng chấp nhận. Ví dụ lớp là hàm distance
, có hai trình lặp và trả về số khoảng trắng giữa chúng. Nếu đầu vào thấp hơn ForwardIterator
hoặc BidirectionalIterator
, điều này hoạt động bằng cách di chuyển các trình vòng lặp về phía trước và đếm số bước đã được thực hiện, chạy trong O (n). Nếu đầu vào là RandomAccessIterator
thì các trình vòng lặp có thể được trừ để nhận kết quả trong O (1).
May mắn thay, bạn thường không phải liệt kê rõ ràng tất cả các typedef. Có một loại tiện ích trong tiêu đề <iterator>
được gọi là iterator
được tham số hóa trên nhiều đối số khác nhau. Nếu bạn xác định một loại trình vòng lặp tùy chỉnh, bạn có thể kế thừa từ iterator
để tự động nhập tất cả thông tin này. Về cơ bản, đây là cách nhanh nhất để có tất cả các typedef
s tại chỗ.
Đối với các nhà khai thác những gì bạn cần để quá tải, ở một mức tối thiểu bạn cần phải nhận được ++
(tiền tố và hậu tố), ==
, !=
, *
(con trỏ dereference), và ->
xác định. Tất cả các loại trình vòng lặp đều hỗ trợ điều này. Đối với các trình vòng lặp hai chiều hoặc cao hơn, bạn cũng cần có --
được xác định (tiền tố và hậu tố). Cuối cùng, cho lặp ngẫu nhiên truy cập, bạn nên hỗ trợ []
, +
, +=
, -
(sao lưu nhiều bước và trừ hai vòng lặp), -=
, <
, >
, <=
, và >=
.
Hy vọng điều này sẽ hữu ích!
Cảm ơn! nếu tôi gõ typedefs trong mã, tôi không cần phải kế thừa std :: iterator nữa? – Sean
@Sean: đúng. Tôi đã viết các trình lặp mà không kế thừa từ 'std :: iterator' và chúng luôn hoạt động tốt (tốt, một số đã có lỗi, nhưng độc lập với' std :: iterator' không phải là nguyên nhân .. .) –