Iterator jest to obiekt, który wskazuje na dany element w kontenerze. W zależności od typu możemy na nim wykonywać różne operacje, np: inkrementować go operator++
, dekrementować operator--
lub wykonywać operacje typu it += 6
. W celu odwołania się do wskazywanego elementu przez iterator używamy operator*
czyli dereferencji (jak na zwykłych wskaźnikach).
Każdy kontener ma 2 końce. Na jeden z nich wskazuje begin()
, a na drugi end()
.
Dla niektórych kontenerów możemy także pobrać odwrotny iterator (ang. reverse iterator) umożliwiający nam przejście wstecz przez zakres.
Jeżeli nie chcemy modyfikować danych wskazywanych przez iterator zastosujemy opcję z przedrostkiem c
pochodzącym od słowa constant
.
-
cbegin()
-
cend()
-
crbegin()
-
crend()
Pytanie, co powinno się znaleźć w miejscu forward_iterator
?
-
std::forward_list
-
std::unordered_set
-
std::unordered_map
Input iterator: pochodzi np. ze strumienia std::istream
, czyli znanego nam std::cin
. Raz wczytane dane znikają, nie możemy ich ponownie odczytać. Mamy możliwość tylko jednorazowego przejścia przez dane. Innym słowem jak tylko odczytamy jakąś daną nasz operator od razu jest inkrementowany.
int a;
int b;
std::cin >> a >> b;
Output iterator: pochodzi np. ze strumienia std::ostream
, czyli znanego nam std::cout
. Raz wypisane dane znikają, nie możemy ich ponownie wyświetlić, musimy ponownie podać dane.
int a;
int b;
std::cin >> a >> b;
std::cout << a << ' ' << b;
Jakie mamy dostępne operatory dla input iterator, a jakie dla output iterator?
Input iterator:
-
operator++
-
operator*
-
operator->
-
operator==
-
operator!=
Output iterator:
-
operator++
-
operator*
Jest to iterator, który umożliwia nam wielokrotne przejście danego zakresu w jedną stronę (w przód).
std::forward_list<int> list {1, 2, 3, 4, 5};
for (auto it = list.begin() ; it != list.end() ; ++it) {
std::cout << *it << '\n';
}
Output: 1 2 3 4 5
Pytanie: Jakie mamy dostępne operatory dla tego iteratora?
-
operator++
-
operator*
-
operator->
-
operator==
-
operator!=
Jest to iterator, który umożliwia nam wielokrotne przejście danego zakresu w obie strony (w przód i tył).
std::list<int> list{1, 2, 3, 4, 5};
for (auto it = list.begin(); it != list.end(); ++it) {
std::cout << *it << ' ';
}
auto last = std::prev(list.end());
for (auto it = last; it != std::prev(list.begin()); --it) {
std::cout << *it << ' ';
}
Output: 1 2 3 4 5 5 4 3 2 1
Pytanie: Jakie mamy dostępne operatory dla tego iteratora?
-
operator++
-
operator*
-
operator->
-
operator==
-
operator!=
-
operator--
Jest to iterator, który umożliwia nam wielokrotne przejście danego zakresu w obie strony (w przód i tył), a także dostęp do dowolnego obiektu.
std::vec<int> vec{1, 2, 3, 4, 5};
for (auto it = vec.begin(); it != vec.end(); ++it) {
std::cout << *it << ' ';
}
auto last = std::prev(vec.end());
for (auto it = last; it != std::prev(vec.begin()); --it) {
std::cout << *it << ' ';
}
std::cout << vec[3];
Output: 1 2 3 4 5 5 4 3 2 1 3
Pytanie: Jakie mamy dostępne operatory dla tego iteratora?
-
operator++
-
operator*
-
operator->
-
operator==
-
operator!=
-
operator--
-
operator<
-
operator<=
-
operator>
-
operator>=
-
operator+
-
operator-
-
operator[]
W C++ 17 wprowadzono jeszcze typ: ContiguousIterator
. Zawiera on wszystkie cechy Random Access iterator oraz zapewnia, że wszystkie dane są ułożone w jednym miejscu w pamięci.