logo

Iteratoren in C++ STL

Een  iterator in C++  is een aanwijzerachtig object dat naar een element van de STL-container verwijst. Ze worden over het algemeen gebruikt om de inhoud van de STL-container in C++ te doorlopen. Het belangrijkste voordeel van STL-iteratoren is dat ze de STL-algoritmen onafhankelijk maken van het gebruikte type container. We kunnen de iterator gewoon doorgeven aan de containerelementen in plaats van de container zelf aan de STL-algoritmen.

Iterator-verklaring

Elke container in C++ STL heeft zijn eigen iterator. We moeten dus een iterator declareren als:



C++
<type>::iterator it; 

waar

  • type: Type container waarvoor de iterator is gedeclareerd.
  • Het: Naam toegewezen aan iteratorobject.

We kunnen het vervolgens initialiseren door een geldige iterator toe te wijzen. Als we al een iterator hebben die moet worden toegewezen op het moment van de delcaratie, kunnen we de typedeclaratie overslaan met behulp van de auto trefwoord.

C++
auto it = iter 

waar iter is de iterator die is toegewezen aan de nieuw gemaakte it-iterator.



Ons C++ cursus omvat het gebruik van iterators in de STL, zodat u begrijpt hoe u verschillende containertypen moet doorlopen.

Voorbeeld van iteratoren

Het onderstaande programma illustreert hoe u de iterator gebruikt om de vectorcontainer te doorlopen:

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

Uitvoer
1 2 3 4 5 

Zoals je misschien gemerkt hebt, hebben we gebruik gemaakt van vector::begin() en vector::end() functie. Deze functies zijn de lidfuncties van std::vector die de iterator retourneren naar het eerste en één element na het laatste element van de vector. We gebruiken de iteratoren die deze functies retourneren om de vectoren te itereren.



Container Iterator-functies

C++ STL biedt enkele lidfuncties in STL-container die de iteratoren retourneren naar ten minste het eerste en het laatste element. Deze lidfuncties zijn gedefinieerd in bijna de hele STL-container (waarbij enkele containers met beperkte toegang overblijven, zoals stapel wachtrij ) met dezelfde naam voor consistentie.

In de volgende tabel worden alle methoden vermeld die de iterator naar de containers retourneren:

Iterator-functie

Retourwaarde

beginnen()

Retourneert een iterator naar het begin van de container.

einde()

Retourneert een iterator naar het theoretische element net na het laatste element van de container.

cbegin()

Retourneert een constante iterator naar het begin van de container. Een constante iterator kan de waarde van het element waarnaar het verwijst niet wijzigen.

een paar()

c++ prototypefunctie

Retourneert een constante iterator naar het theoretische element net na het laatste element van de container.

rbegin()

Retourneert een omgekeerde iterator naar het begin van de container.

veroorzaken()

Retourneert een omgekeerde iterator naar het theoretische element net na het laatste element van de container.

crbegin()

Retourneert een constante omgekeerde iterator naar het begin van de container.

CREND ()

Retourneert een constante omgekeerde iterator naar het theoretische element net na het laatste element van de container.

Bijvoorbeeld als een ding is de naam van de vector, dan kunnen we de bovenstaande methoden gebruiken, zoals hieronder weergegeven:

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

Iterator-operaties

Net als bij aanwijzerberekeningen zijn er enkele bewerkingen toegestaan ​​op C++-iterators. Ze worden gebruikt om verschillende functionaliteiten te bieden die het belang van iteratoren vergroten. Er zijn er 5 geldig iteratorbewerkingen in C++ :

  • Dereferentie van iterators
  • Iteratoren verhogen/verlagen
  • Geheel getal optellen/aftrekken van iteratoren
  • Een andere iterator aftrekken
  • Iteratoren vergelijken

Dereferentie van iterators

Door het verwijderen van verwijzingen kunnen de gebruikers dat doen openen of bijwerken de waarde van het element waarnaar de iterator verwijst. Wij gebruiken de (*) indirecte operator om iterators te derefereren, net als pointers.

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

waar nieuwe_val is de nieuwe waarde die is toegewezen aan het element waarnaar door de iterator wordt verwezen Het .

Iteratoren verhogen/verlagen

We kunnen de iterator met 1 verhogen of verlagen met behulp van (++) of (--) operatoren respectievelijk. De ophoogbewerking verplaatst de iterator naar het volgende element in de container, terwijl de afbouwbewerking de iterator naar het vorige element verplaatst.

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

Geheel getal optellen/aftrekken van iteratoren

We kunnen ook een geheel getalwaarde optellen of aftrekken van de iteratoren. Het zal meer de volgende of vorige positie van de iterator zijn, afhankelijk van de toegevoegde gehele waarde.

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

waar int_val zijn de gehele waarden die worden opgeteld of afgetrokken van de iterator Het .

Een andere iterator aftrekken

We kunnen de ene iterator van de andere aftrekken om de afstand (of het aantal elementen) te vinden tussen het geheugen waarnaar ze verwijzen.

C++
it1 - it2 

Iteratoren vergelijken

We kunnen ook de twee iterators van hetzelfde type tegen elkaar testen om de relatie daartussen te vinden. We kunnen de relationele operatoren zoals (==) gelijkheids- en (!=) ongelijkheidsoperatoren gebruiken, samen met andere relationele operatoren zoals< > <= >=.

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 

Soorten iteratoren in C++

STL-iteratoren kunnen worden onderverdeeld op basis van de bewerkingen die erop kunnen worden uitgevoerd. Er zijn 5 hoofdtypen iterators in C++, zoals vermeld in de onderstaande tabel, samen met ondersteunde containers en ondersteunde iteratorbewerkingen.

Iterator

Beschrijving

Ondersteunde containers

Ondersteunde operaties

Invoeriterator

Het is een eenrichtings-iterator die wordt gebruikt om de waarden te lezen.

Invoerstroom

Dereferentie van toenemende gelijkheid

Uitvoeriterator

Het is ook een eenrichtings-iterator, maar wordt gebruikt om de waarden toe te wijzen. Het heeft geen toegang tot de waarden.

Uitvoerstroom

Dereferentie verwijderen (alleen schrijven) Verhogen

Voorwaartse iteratoren

Het heeft toegang tot de waarden en kan deze ook toewijzen. Het is de combinatie van zowel invoer- als uitvoeriterator.

forward_list ongeordende_kaart ongeordende_set

Dereferentie van toenemende gelijkheid

Bidirectionele iteratoren

Het kan in beide richtingen bewegen, zowel voorwaarts als achterwaarts. De containers zoals lijstset en multimap ondersteunen bidirectionele iterators.

lijst kaartset multimap multiset

Dereferentie van gelijkheid verhogen/verlagen

Random Access-iteratoren

Iterators met willekeurige toegang zijn iterators die kunnen worden gebruikt om toegang te krijgen tot elementen op afstand van het element waarnaar ze verwijzen, en bieden dezelfde functionaliteit als pointers.

vector deque array-reeks

Java-erfenis

Alle

Zoals we misschien hebben opgemerkt in de bovenstaande tabel, afgezien van de invoer- en uitvoeriteratoren Naarmate we verder in de tabel komen, bevat het iteratortype de functies van de bovenstaande iterator, samen met enkele nieuwe functies.

Iterator-adapters

Iteratoradapters in C++ zijn het speciale type iterators die over traditionele iterators heen zijn gebouwd om gespecialiseerde functionaliteit te bieden. Er zijn veel iteratoradapters in C++, waarvan er enkele hieronder worden gegeven:

Type iteratoradapters

Beschrijving

Omgekeerde iterator

De omgekeerde iterator is gebouwd over een bidirectioneel of hoger type operator en stelt gebruikers in staat de container in de omgekeerde richting te doorkruisen.

Stream-iterators

De stream-iteratoren, namelijk istream- en ostream-iteratoren, zijn respectievelijk gebouwd op de invoer- en uitvoer-iteratoren. Met deze iterators kunnen gebruikers de streams als containers gebruiken.

Verplaats iteratoren

Verplaatsiteratoren worden gebruikt om de verplaatsingssemantiek in STL-algoritmen te introduceren. De verplaatsingiterators verplaatsen het eigendom van de gekopieerde containergegevens naar de kopieercontainer zonder de extra kopieën te maken.

Inserter-iterator

Met de insertor-iteratoren kunt u de gegeven elementen op een bepaalde positie in de container invoegen. Er zijn drie insertor-iterators in C++:

  1. back_insert_iterator: Inzetstukken aan de achterkant van de container.
  2. front_insert_iterator: Inzetstukken aan de voorkant van de container.
  3. insert_iterator: Kan overal in de container worden geplaatst.

Deze iterators kunnen worden gemaakt met behulp van back_inserter() front_inserter() invoegen() functies in C++.

Iterator-hulpprogrammafuncties in C++

C++ STL biedt verschillende functies om het werken met iteratoren te vereenvoudigen. Ze staan ​​vermeld in de onderstaande tabel:

Functie Beschrijving Syntaxis
standaard::vooruitgang Zet een iterator een bepaald aantal posities vooruit. voorschot ( het n )
std::volgende Retourneert de iterator die een opgegeven aantal posities vóór ligt op de gegeven iterator. volgende ( het n )
Std :: Vorige Retourneert de iterator die een opgegeven aantal posities achter de gegeven iterator ligt. vorige ( het n )
standaard::afstand Retourneert het aantal elementen tussen twee iterators. afstand ( het1 het2 )
std::beginRetourneert een iterator naar het eerste element van de gegeven container. beginnen ( houder )
std::eindeRetourneert een iterator naar het element dat volgt op het laatste element van de gegeven container. einde ( houder )
std::rbeginRetourneert een omgekeerde iterator naar het laatste element van de gegeven container. rbegin ( houder )
std::rendRetourneert een omgekeerde iterator naar het element dat voorafgaat aan het eerste element van de gegeven container. maakt ( houder )
std::invoeger Creëert een invoeg-iterator die elementen op een opgegeven positie in een container invoegt. invoeger ( containerpositie )
std::back_inserter Creëert een back-insert-iterator die elementen aan het einde van een container toevoegt. back_inserter ( houder )
std::front_inserter Creëert een front insert iterator die elementen aan de voorkant van een container invoegt. front_inserter ( houder )

Toepassingen van iterators met voorbeelden

Iterators worden veelvuldig gebruikt in C++ voor veel verschillende doeleinden tijdens het werken met STL-containers en algoritmen. Hieronder volgen enkele primaire toepassingen van iterators in C++ met hun codevoorbeelden:

Containers doorkruisen

Het doorkruisen van STL-containers is de meest basale toepassing van iterators. Hierin gebruiken we de functies begin() en end() om de begin- en einditeratoren de hele container te laten doorlopen. In principe blijven we de begin-iterator verhogen totdat deze niet gelijk is aan het einde.

Voorbeeld

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

Uitvoer
10 20 30 40 50 

Zoals weergegeven in de bovenstaande code doorkruisen we de ingestelde container. Op dezelfde manier kunnen we dezelfde aanpak gebruiken om elke container te doorkruisen.

Het omkeren van een container

Met omgekeerde iterators kunt u een container van het einde naar het begin doorlopen zonder dat u de omkering handmatig hoeft af te handelen.

Voorbeeld

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

Uitvoer
50 40 30 20 10 

Container-onafhankelijke algoritmen

Met iterators kunnen algoritmen met elk containertype werken, waardoor functies als std::sort() std::find() en std::for_each() flexibeler worden. U kunt iterators doorgeven in plaats van de daadwerkelijke container.

Voorbeeld

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

Uitvoer
10s in Vector: 2 10s in Multiset: 3

Aanvullende toepassingen van iteratoren

Er zijn meer toepassingen van STL-iteratoren:

  • Afstandsberekening: Met behulp van std::distance() iterators kunt u het aantal elementen tussen twee posities in een container berekenen.
  • Stream-iteratie: Met streamiterators kunt u invoer-/uitvoerstreams behandelen als containers, waardoor het gemakkelijker wordt om streams te lezen en ernaar te schrijven met behulp van STL-algoritmen.
  • Verplaats semantiek in STL-algoritmen: Verplaatsiterators introduceren de verplaatsingssemantiek in STL-algoritmen, wat helpt bij het verbeteren van de prestaties en efficiëntie door onnodig kopiëren te voorkomen. De gegevens worden verplaatst volgens de regels van de verplaatsingssemantiek.
  • Aangepaste iterators voor gegevensstructuren: Aangepaste iterators kunnen worden geïmplementeerd voor niet-STL-gegevensstructuren zoals bomen of grafieken om ondersteuning te bieden voor STL-algoritmen en vele andere functies. Mogelijk moeten we een aantal regels en conventies volgen om de juiste oplopende, aflopende en andere bewerkingen te kunnen uitvoeren.