01/10/2018, 15:36
Iterator có khác gì với pointer không?
Cho mình hỏi iterator có khác gì với pointer không? Thực ra ban đầu mình nghĩ iterator là index, nhưng search mạng thì thấy là không phải. (mình lập trình C++, tại liên quan đến vector::begin() nên mình tìm hiểu)
Bài liên quan
iterator cũng là pointer nhé! std::vector::begin() và std::vector::end() ( or cbegin(), cend() ) đều trả về iterator ngay tại index đầu và kế cuối (last - 1)
https://www.cs.northwestern.edu/~riesbeck/programming/c++/stl-iterators.html
std::X::begin()
,::(r)end()
,::back()
.có khác, bạn vô đây tìm hiểu thêm: http://en.cppreference.com/w/cpp/iterator
.
.
mấy cái này là “khái niệm” - concept, nó na ná với interface nhưng ko phải interface vì nó được dịch lúc compile, trong khi interface được “dịch” lúc chạy chương trình.
.
.
Iterator: là kiểu có thể gọi
*it
và++it
, và có copy ctorIt it2 = it1;
, có toán tử gán:it1 = it2
, có hàm hủy, có thể swap được, và có thêm mấy typedef cho mấy kiểu mà nó xài nữa:It::value_type
,It::difference_type
,It::reference
,It::pointer
,It::iterator_category
InputIterator: thỏa mãn các khái niệm của Iterator, cộng thêm toán tử so sánh bằng/khác nhau:
it1 == it2
,it1 != it2
, và đặc biệt*it
chỉ xài được 1 lần (single pass), deref lần 2 ko được, ví dụit2 = it1; *it1; /*ok*/ *it2; /*not ok*/
. Ví dụ của input iterator làstd::istreambuf_iterator
: chỉ đọc ký tự trích từ input stream 1 lần, ko đọc được lần thứ 2. Ví dụ để đọc toàn bộ nội dung của 1 file:OutputIterator: thỏa mãn khái nhiệm Iterator, và câu lệnh
*it = x;
là hợp lệ. (InputIterator ko cần thiết phải gán*it = x;
, nếu 1 iterator gán x cho *it được thì nó là OutputIterator)ForwardIterator: thỏa mãn khái niệm InputIterator,
*it
xài được nhiều lần (multi pass). Kiểu trả về của*it
làIt::reference
có thể làconst T&
, hoặcT&
nếu iterator này cũng thỏa mãn khái niệm OutputIterator. Ví dụ: con trỏ của danh sách liên kết đơn.BidirectionalIterator: thỏa mãn khái niệm ForwardIterator, cộng thêm khả năng decrement:
--it
vàit--
. Ví dụ: con trỏ của danh sách liên kết đôi.RandomAccessIterator: thỏa mãn khái niệm BidirectionalIterator, cộng thêm khả năng cộng trừ số nguyên:
it += n
,it -= n
,it + n
,it - n
và so sánh lớn bé:it1 < it2
,it1 > it2
,it1 <= it2
,it1 >= it2
. Ví dụ: con trỏ của mảng C, con trỏ của mảng C++std::array<T>
, con trỏ củastd::vector<T>
, con trỏ củastd::deque<T>
ngoài ra còn có khái niệm ContiguousIterator, nó giống hệt RandomAccessIterator, chỉ trừ
vector<bool>::iterator
là ko thỏa mãn khái niệm ContiguousIterator này. Phải thêm ông này vào chỉ vì thằngvector<bool>
… Vớivector<T>::iterator
, bạn có thể chuyển iterator thành con trỏ bằng cách xàiT* ptr = &*it;
, chỉ duy nhất có ôngvector<bool>::iterator
là ko thể lấy con trỏbool*
như vậy được, nên mới phải đẻ ra khái niệm mới ContiguousIterator này. Edit:std::deque<T>::iterator
với T bất kì cũng ko thỏa mãn khái niệm ContiguousIterator.tương lai ko còn xài khái niệm iterator nữa mà xài khái niệm range gì đó @_@