Skip to content

Latest commit

 

History

History
204 lines (143 loc) · 6.84 KB

iterators.md

File metadata and controls

204 lines (143 loc) · 6.84 KB

Iteratory


Krótka powtórka #1

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).


Krótka powtórka #2

Każdy kontener ma 2 końce. Na jeden z nich wskazuje begin(), a na drugi end().


Krótka powtórka #3

Dla niektórych kontenerów możemy także pobrać odwrotny iterator (ang. reverse iterator) umożliwiający nam przejście wstecz przez zakres.


Krótka powtórka #4

Jeżeli nie chcemy modyfikować danych wskazywanych przez iterator zastosujemy opcję z przedrostkiem c pochodzącym od słowa constant.

  • cbegin()
  • cend()
  • crbegin()
  • crend()

Hierarchia iteratorów

Pytanie, co powinno się znaleźć w miejscu forward_iterator?

  • std::forward_list
  • std::unordered_set
  • std::unordered_map

"Najbiedniejsze" iteratory, czyli input i output

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;

Pytanie

Jakie mamy dostępne operatory dla input iterator, a jakie dla output iterator?

Input iterator:

  • operator++
  • operator*
  • operator->
  • operator==
  • operator!=

Output iterator:

  • operator++
  • operator*

Forward iterator

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!=

Bidirectional iterator

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--

Random Access iterator

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


Random Access iterator

Pytanie: Jakie mamy dostępne operatory dla tego iteratora?

  • operator++
  • operator*
  • operator->
  • operator==
  • operator!=
  • operator--
  • operator<
  • operator<=
  • operator>
  • operator>=
  • operator+
  • operator-
  • operator[]

Ciekawostka

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.


Q&A