logo

Итератори в C ++ STL

An  итератор в C ++  е обект, подобен на показалец, който сочи елемент от контейнера STL. Обикновено се използват за преминаване през съдържанието на контейнера STL в C ++. Основното предимство на STL итераторите е, че те правят алгоритмите STL независими от типа на използвания контейнер. Можем просто да предадем итератора на елементите на контейнера вместо самия контейнер към алгоритмите STL.

Итератор Декларация

Всеки контейнер в C ++ STL има свой итератор. Така че трябва да декларираме итератор като:



C++
<type>::iterator it; 

Къде

  • Тип: Тип контейнер, за който е деклариран итераторът.
  • то: Име, присвоено на итератор обект.

След това можем да го инициализираме, като присвоим някакъв валиден итератор. Ако вече имаме итератор, който да бъде назначен по време на Delcaration, тогава можем да пропуснем декларацията от типа, използвайки Авто ключова дума.

C++
auto it = iter 

Къде итер е итераторът, присвоен на новосъздадения го итератор.



Нашите C ++ курс Покрива използването на итератори в STL, гарантирайки, че разбирате как да преминете към различни типове контейнери.

Пример за итератори

Програмата по -долу илюстрира как да използвате итератора за преминаване на векторния контейнер:

C++
#include    using namespace std; int main() {  vector<int> v = {1 2 3 4 5};  // Defining an iterator pointing to  // the beginning of the vector  vector<int>::iterator first =  v.begin();  // Defining an iterator pointing  // to the end of the vector  vector<int>::iterator last =  v.end();    // Iterating the whole vector  while(first != last) {  cout << *first << ' ';  first++;  }  return 0; } 

Изход
1 2 3 4 5 

Както може би сте забелязали, че сме използвали вектор :: begin () и вектор :: end () функция. Тези функции са функциите на членовете на std :: вектор, който връща итератора на първия и един елемент след последния елемент на вектора. Използваме итераторите връщат тези функции, за да повтаряме векторите.



Итератор на контейнера функции

C ++ STL предоставя някои функции на членовете в STL контейнер които връщат итераторите поне на първия и последния елемент. Тези функции на членовете са дефинирани в почти целия контейнер STL (оставяйки някои контейнери с ограничен достъп като стек опашка ) със същото име за последователност.

Следващата таблица изброява всички методи, които връщат итератора в контейнерите:

Итератор функция

Връщане на стойност

begin ()

Връща итератор в началото на контейнера.

край ()

Връща итератор към теоретичния елемент веднага след последния елемент на контейнера.

cbegin ()

Връща постоянен итератор в началото на контейнера. Постоянният итератор не може да променя стойността на елемента, към който се насочва.

Няколко ()

uri срещу url

Връща постоянен итератор на теоретичния елемент непосредствено след последния елемент на контейнера.

rbegin ()

Връща обратна итератор в началото на контейнера.

render ()

Връща обратния итератор на теоретичния елемент непосредствено след последния елемент на контейнера.

crbegin ()

Връща постоянен обрат на итератор в началото на контейнера.

Crend ()

Връща постоянен обратна итератор на теоретичния елемент непосредствено след последния елемент на контейнера.

Например, ако нещо е името на вектора, тогава можем да използваме горните методи, както е показано по -долу:

C++
vec.begin() vec.rbegin() vec.cbegin() vec.crbegin() vec.end() vec.rend()  vec.cend() vec.crend() 

Итератори операции

Точно като аритметиката на показалеца има някои операции, които са разрешени на итератори C ++. Те се използват за осигуряване на различни функционалности, които увеличават значението на итераторите. Има 5 валидни Итераторни операции в C ++ :

  • Итератори на дефериране
  • Увеличаване/намаляване на итератори
  • Добавяне/изваждане на цяло число към итераторите
  • Изваждане на друг итератор
  • Сравняване на итератори

Итератори на дефериране

Операцията за дефериране позволява на потребителите да достъп или актуализация Стойността на елемента, насочен от итератора. Използваме (*) оператор на индирекция за итератори на дереференция точно като указатели.

C++
// Access *it; // Update *it = new_val;  

Къде new_val е новата стойност, присвоена на елемента, насочен от итератора то .

Увеличаване/намаляване на итератори

Можем да увеличим или намалим итератора с 1, използвайки (++) или (-) оператори съответно. Операцията за привличане премества итератора към следващия елемент в контейнера, докато операцията по декремент премества итератора към предишния елемент.

C++
it++; // post-increment ++it; // pre-increment it--; // post-decrement --it; // pre-decrement 

Добавяне/изваждане на цяло число към итераторите

Можем също така да добавим или извадим цяло число от итераторите. Той ще бъде повече итератор следващата или предишната позиция според добавената цяло число.

C++
// Addition it + int_val;  // Subtraction it - int_val;  

Къде int_val са целочислените стойности, които се добавят или изваждат от итератора то .

Изваждане на друг итератор

Можем да извадим един итератор от друг, за да намерим разстоянието (или броя на елементите) между паметта, към която сочат.

C++
it1 - it2 

Сравняване на итератори

Можем също да тестваме двата итератора от един и същи тип един срещу друг, за да намерим връзката между тях. Можем да използваме релационните оператори като (==) равенство и (! =) Оператори на неравенство заедно с други релационни оператори като< > <= >=.

C++
it1 != it2 // Equal to it1 == it2 // Not equal to it1 > it2 // Greater than it1 < it2 // Less than it1 >= it2 // Greater than equal to it1 <= it2 // Less than equal to 

Видове итератори в C ++

STL итераторите могат да бъдат разделени въз основа на операциите, които могат да бъдат извършени върху тях. В C ++ има 5 основни типа итератори, които са посочени в таблицата по -долу, заедно с поддържани контейнери и поддържани операции на итератор.

Итератор

Описание

Поддържани контейнери

Поддържани операции

Итератор за въвеждане

Това е еднопосочен итератор, използван за четене на стойностите.

Входен поток

Равенство на увеличение на дефектиране

Изходен итератор

Освен това е еднопосочен итератор, но се използва за присвояване на стойностите. Той не може да получи достъп до стойностите.

Изходен поток

Дерефериране (само за писане) нарастване

Итератори напред

Той може да има достъп и както и да присвои стойностите. Това е комбинацията от вход и изходен итератор.

forward_list unordered_map unordered_set

Равенство на увеличение на дефектиране

Двупосочни итератори

Той може да се движи в двете посоки или в напред или назад. Контейнерите като списък на списъка и MultiMap поддържа двупосочни итератори.

Списък на картата MultiMap Multiset

Равенство на увеличение/намаляване на дефектиране

Итератори за произволен достъп

Итераторите за произволен достъп са итератори, които могат да се използват за достъп до елементи на разстояние от елемента, който сочат към предлагане на същата функционалност като указателите.

векторна низ от масив Deque

sanjay dutt и

Всички

Както може би сме забелязали от горната таблица, освен итераторите за вход и изход Когато слизаме по масата, типът итератор съдържа характеристиките на над итератора заедно с някои нови функции.

Итераторни адаптери

Итераторните адаптери в C ++ са специалният тип итератори, които са изградени върху традиционните итератори, за да осигурят специализирана функционалност. В C ++ има много итераторни адаптери, някои от които са дадени по -долу:

Итератор адаптери тип

Описание

Обратна итератор

Обратният итератор е изграден над двупосочен или над тип оператор и позволява на потребителите да преминат към контейнера в обратна посока.

Итератори на потока

Итераторите на потока, а именно ISTREAM и итераторите на Ostream са изградени съответно върху итераторите в вход и изход. Тези итератори позволяват на потребителите да използват потоците като контейнери.

Преместване на итератори

Итераторите за движение се използват за въвеждане на семантиката на движение в алгоритмите на STL. Итераторите за преместване преместват собствеността върху копираните данни за контейнера в копиращия контейнер, без да създават допълнителни копия.

Итератор на вмъкване

Итераторите на Insertor ви позволяват да поставите дадените елементи в някаква позиция в контейнера. В C ++ има три итератора за вмъкване:

  1. back_insert_iterator: Вложки в задната част на контейнера.
  2. front_insert_iterator: Вложки в предната част на контейнера.
  3. insert_iterator: Вмъква се навсякъде в контейнера.

Тези итератори могат да бъдат създадени с помощта на back_inserter () front_inserter () вмъкване () функции в C ++.

Итераторни полезни функции в C ++

C ++ STL предоставя различната функция за опростяване на работата с итератори. Те са изброени в таблицата по -долу:

Функция Описание Синтаксис
std :: аванс Напредва итератор по определен брой позиции. аванс ( то n )
std :: Напред Връща итератора, който е определен брой позиции пред дадения итератор. След това ( то n )
std::prev Връща итератора, който е определен брой позиции зад дадения итератор. Преди ( то n )
std :: разстояние Връща броя на елементите между два итератора. разстояние ( it1 it2 )
std :: започнетеВръща итератор към първия елемент от дадения контейнер. започнете ( контейнер )
std :: крайВръща итератор в елемента, следвайки последния елемент от дадения контейнер. край ( контейнер )
std :: rbeginВръща обратния итератор към последния елемент на дадения контейнер. rbegin ( контейнер )
std :: rendВръща обратна итератор към елемента, предхождащ първия елемент от дадения контейнер. прави ( контейнер )
std :: вмъкване Създава итератор за вмъкване, който вмъква елементи в контейнер в определено положение. вмъкване ( позиция на контейнера )
std :: back_inserter Създава итератор за вмъкване на гърба, който добавя елементи към края на контейнер. back_inserter ( контейнер )
std :: front_inserter Създава итератор на предната вложка, който вмъква елементи в предната част на контейнер. front_inserter ( контейнер )

Приложения на итератори с примери

Итераторите се използват широко в C ++ за много различни цели, докато работят с STL контейнери и алгоритми. Следват някои основни приложения на итератори в C ++, които техните кодови примери:

Преминаване на контейнери

Преминаването на STL контейнерите е най -основното приложение на итераторите. В това използваме функциите begin () и end (), за да накараме итераторите за начало и край да прехвърлят целия контейнер. По принцип продължаваме да увеличаваме началния итератор, докато не е равен на края.

Пример

C++
#include    using namespace std; int main() {  set<int> s = {10 20 30   40 50};  // Iterator to the beginning   // of the set  auto it = s.begin();  // Iterating through the   // entire set  while (it != s.end()) {    // Dereferencing iterator   // to access value  cout << *it << ' ';    // Incrementing the   // iterator  it++;  }    return 0; } 

Изход
10 20 30 40 50 

Както е показано в кода по -горе, ние преминаваме към контейнера за задаване. По същия начин можем да използваме същия подход за преминаване на всеки контейнер.

Обръщане на контейнер

Обратните итератори ви позволяват да преминете към контейнер от края до началото, без да е необходимо ръчно да обработвате обръщането.

Пример

C++
#include    using namespace std; int main() {  vector<int> vec = {10 20 30   40 50};  // Defining reverse iterators   // pointing to the reverse   // beginning of vec  auto it = vec.rbegin();  // Iterating the whole   // vector in reverse  while (it != vec.rend()) {  cout << *it << ' ';  it++;  }  return 0; } 

Изход
50 40 30 20 10 

Независими от контейнерите алгоритми

Итераторите позволяват на алгоритмите да работят с всеки тип контейнер, който прави функции като std :: shore () std :: find () и std :: for_each () по -гъвкав. Можете да предавате итератори вместо действителния контейнер.

Пример

C++
#include    using namespace std; int main() {  vector<int> vec = {30 10 40   10 50};  multiset<int> ms = {10 30 10   20 40 10};  // Using the std::count() algorithm to count  // the number of occurences of 10 in vector  // and multiset using iterator  cout << '10s in Vector: '   << count(vec.begin()  vec.end() 10) << endl;  cout << '10s in Multiset: '   << count(ms.begin()  ms.end() 10);  return 0; } 

Изход
10s in Vector: 2 10s in Multiset: 3

Допълнителни приложения на итератори

Има още приложения на STL итератори:

  • Изчисляване на разстоянието: Използването на std :: итератори разстояние () помагат да се изчисли броят на елементите между две позиции в контейнер.
  • Итерация на потока: Итераторите на потока ви позволяват да третирате входни/изходни потоци като контейнери, което улеснява четенето от и пишете в потоци, използвайки алгоритми STL.
  • Преместете семантиката в алгоритмите STL: Iterators Move въвежда Move Semantics в алгоритмите на STL, което помага за повишаване на производителността и ефективността, като избягва ненужното копиране. Данните ще бъдат преместени според правилата на семантиката на движението.
  • Персонализирани итератори за структури от данни: Персонализираните итератори могат да бъдат внедрени за не-STL структури от данни като дървета или графики, за да се осигури поддръжката за STL алгоритми и много други функции. Може да се наложи да следваме няколко набора от правила и конвенции, за да осигурим правилно намаляване на увеличението и други операции.