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)
Iterator có khác gì với pointer không?
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
- Bạn không thể ++ pointer để duyệt tree được
nhưng ++ iterator thì được. - Pointer chỉ trỏ đến đối tượng, còn iter gắn chặt với cấu trúc STL có liên quan. Vì vậy dễ dàng lấy được các iter quan trọng:
std::X::(r)begin(),::(r)end(),::back(). - Có những iterator chỉ đọc, không cho ghi. Xem link phía trên để biết thêm chi tiết.
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 ctor It 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:
std::ifstream f("file.txt");
std::string content((std::istreambuf_iterator<char>(f)),
std::istreambuf_iterator<char>());
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ặc T& 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ủa std::vector<T>, con trỏ của std::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ằng vector<bool>… Với vector<T>::iterator, bạn có thể chuyển iterator thành con trỏ bằng cách xài T* ptr = &*it;, chỉ duy nhất có ông vector<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ì đó @_@
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?