C++ vektorové iterátory

C Vektorove Iteratory



Hlavními iterátory v C++ jsou Input Iterator, Output Iterator, Forward Iterator, Bidirectional Iterator a Random Access Iterator. Reverzní iterátor ve skutečnosti není iterátor; je to iterátorový adaptér. Existují některé varianty iterátorů, jako je konstantní iterátor.

Iterátor je propracovaný ukazatel. Jako ukazatel ukazuje na objekty stejného typu v paměti v různých časech. Všechny iterátory jsou dereferovatelné, kromě iterátoru výstupu, který je dereferencovatelný pouze pro sadu typů. Dereferenceable znamená, že hodnotu, na kterou ukazuje ukazatel nebo iterátor, lze získat pomocí operátoru nepřímosti, *. K některým iterátorům lze stejným způsobem přidat celé číslo a za stejným účelem by se celé číslo přidalo k ukazateli.

Otázky pro tento článek jsou: Co jsou tyto iterátory? Které z těchto iterátorů se používají s vektorem C++? Jak se tyto iterátory používají s vektorem C++? Tento článek odpovídá na všechny tyto otázky zjednodušeným způsobem. Na konci tohoto článku, až budou všechny tyto otázky zodpovězeny, budou vektorové iterátory C++ intuitivní a přirozené (pro čtenáře).







Obsah článku

Shrnutí iterátorů C++

Iterátor vstupu



Myšlenka iterátoru vstupu spočívá v tom, že program přijímá vstupní hodnotu. Na rozdíl od výstupního iterátoru je vstupní iterátor vždy dereferencovatelný. Pro dva vstupní iterátory, aab, „a == b“ neznamená „++a == ++b“.



Iterátor výstupu
Myšlenka iterátoru výstupu spočívá v tom, že program uvolní výstupní hodnotu. Na rozdíl od vstupního iterátoru není výstupní iterátor vždy dereferencovatelný. Je dereferencovatelná pouze pro sadu typů.





Dopředný iterátor
Dopředný iterátor může skenovat vektor od začátku do konce, jeden po druhém (zvyšování). Má všechny požadavky vstupního iterátoru plus další požadavky. Může nahradit iterátor vstupu. Pro dva dopředné iterátory aab, „a == b“ znamená „++a == ++b“.

Obousměrný iterátor
Obousměrný iterátor může skenovat vektor od začátku do konce, jeden po druhém. Od konce do začátku, jeden po druhém (snižování). Má všechny požadavky dopředného iterátoru plus další požadavky. Může nahradit dopředný iterátor. Pro dva obousměrné iterátory, a a b,



„a == b“ znamená „++a == ++b“
a
„–a == –b“ znamená „a == b“.

Iterátor náhodného přístupu

Iterátor náhodného přístupu má všechny požadavky obousměrného iterátoru a navíc další požadavky. Může nahradit obousměrný iterátor. Iterátor náhodného přístupu má tu výhodu, že pokud aktuálně ukazuje na první prvek a je vyžadován čtvrtý prvek, přeskočí druhý a třetí prvek a ukáže na čtvrtý prvek. Opačné přeskakování dolů je pravda.

Reverzní iterátor

Všimněte si, že C++ nemá normální zpětný iterátor, protože má dopředný iterátor. Existuje tedy adaptér zvaný Reverse Iterator. Je tu další dobrá zpráva: reverzní iterátor splňuje všechny požadavky obousměrného iterátoru.

Konstantní iterátor

Pokud je iterátor označen za const iterator, prvek, na který ukazuje, nelze upravit.

Vektorové konstrukce a přístup

Kontejnery v C++ jsou: pole tříd, deque, forward_list, list, vector, map, set, unordered_map a unordered_set. Vektor je kontejner. Některé šablony funkcí ve standardní knihovně C++ pracují s iterátory přímo nebo nepřímo. Tyto funkce využívají kontejnery C++, stejně jako vektor. Tyto funkce lze zpřístupnit programu C++ pomocí některé z následujících inkluzních direktiv:

#include

nebo

#include

Zahrnutí jakéhokoli jiného kontejneru zpřístupní také tyto šablony funkcí. Šablona funkce je pro funkci, která může pracovat s různými datovými typy. Vektor používá iterátory prostřednictvím těchto šablon funkcí. Některé šablony funkcí a jejich vztah k vektoru jsou následující:

Konstrukce

Funkce šablony:

šablona < třída C > constexpr auto data ( C & C ) - > decltype ( C. data ( ) ) ;

auto znamená, že návratový typ je určen při vyhodnocení funkce. c je objekt třídy C.

Příklad vektorového objektu vytvořeného tímto implicitně je:

vektor < char > vtr ;

Zde je objekt c prázdný.

Funkce šablony:

šablona < třída A > constexpr konst A * data ( seznam inicializátorů < A > The ) no kromě ;

Zde je E* iterátor, který ukazuje na první prvek seznamu nebo kontejneru. Jeho použití s ​​vektorem implicitně by bylo s:

vektor < char > vtr { 'A' , 'B' , 'C' , 'D' , 'A' } ;
vektor < char > :: const_iterator to = vtr. začít ( ) ;

Funkce šablony je více použitelná pro příkaz začátek () (druhý příkaz).

Přístup

Funkce šablony:

šablona < třída C > constexpr auto velikost ( konst C & C ) - > decltype ( C. velikost ( ) ) ;

Tím se vrátí velikost kontejneru. Vektorový příklad:

vektor < char > vtr { 'A' , 'B' , 'C' , 'D' , 'A' } ;
int N = vtr. velikost ( ) ;
cout << N << endl ;

Výstup je 5.

Funkce šablony:

šablona < třída A > [ [ nodiscard ] ] constexpr bool prázdný ( seznam inicializátorů < A > The ) no kromě ;

Vrátí hodnotu true, pokud je seznam prázdný nebo v opačném případě nepravda. Vektorový příklad:

vektor < char > vtr { 'A' , 'B' , 'C' , 'D' , 'A' } ;
bool s = vtr. prázdný ( ) ;
cout << s << endl ;

Výstup je 0 pro false.

Přístup k dosahu

Existují další šablonové funkce, které používají iterátory, které vektor používá pro své problémy s rozsahem. Rozsah je po sobě jdoucí sada prvků kontejneru.

Funkce šablony:

šablona < třída C > constexpr auto začít ( C & C ) - > decltype ( C. začít ( ) ) ;

To vrátí iterátor ukazující na první prvek v seznamu. auto zde znamená, že návratová hodnota je určena při vyhodnocení. Příklad pro vektor:

vektor < char > vtr { 'A' , 'B' , 'C' , 'D' , 'A' } ;
vektor < char > :: iterátor to = vtr. začít ( ) ;
cout << * to << ' \n ' ;

Výstup je A. Zde vrácený iterátor je iterátor s náhodným přístupem. Mohl být vrácen konstantní iterátor náhodného přístupu – viz dále.

Šablona funkce:

šablona < třída C > constexpr auto konec ( konst C & C ) - > decltype ( C. konec ( ) ) ;

Vrátí konstantní iterátor ukazující na poslední prvek seznamu. Kód vektoru:

vektor < char > vtr { 'A' , 'B' , 'C' , 'D' , 'A' } ;
vektor < char > :: const_iterator to = vtr. konec ( ) ;
-- to ;
cout << * to << ' ' ;
-- to ;
cout << * to << endl ;

Výstup je „E D“. Konstantní iterátor lze zvýšit nebo snížit, ale hodnotu, na kterou ukazuje, nelze změnit. Mohl být vrácen normální iterátor náhodného přístupu – viz dále.

Šablona funkce:

šablona < třída A > constexpr reverzní_iterátor < konst A * > začít ( seznam inicializátorů < A > The ) ;

Vrátí poslední hodnotu v seznamu. rbegin() ukazuje na poslední prvek seznamu a ne za poslední prvek seznamu, jako to dělá end(). Vektorový příklad:

vektor < char > vtr { 'A' , 'B' , 'C' , 'D' , 'A' } ;
vektor < char > :: reverzní_iterátor to = vtr. začít ( ) ;
cout << * to << ' ' ;
++ to ;
cout << * to << endl ;

Výstup je: E D. S reverzním iterátorem má ++ opačný účinek pro obousměrný iterátor.

Šablona funkce:

šablona < třída A > constexpr reverzní_iterátor < konst A * > dělá ( seznam inicializátorů < A > The ) ;

Body těsně před prvním prvkem seznamu. Vektorový příklad:

vektor < char > vtr { 'A' , 'B' , 'C' , 'D' , 'A' } ;
vektor < char > :: reverzní_iterátor to = vtr. dělá ( ) ;
-- to ;
cout << * to << ' ' ;
-- to ;
cout << * to << endl ;

Výstup je A B. S obráceným iterátorem — má opačný účinek pro ++ obousměrného iterátoru.

Pod tímto nadpisem jsou další funkce šablony – viz dále.

Vložit iterátory

reverse_iterator je adaptér iterátoru, nikoli ve skutečnosti iterátor. Vložit iterátor je také adaptér iterátoru. Splňuje všechny požadavky výstupního iterátoru plus jeho vlastní požadavky. V C++ existuje ve třech formách: back_inserter, front_inserter a inserter. Každý z nich má svůj vlastní konstruktor.

back_inserter:

Vsadky vzadu!
Důležité prototypy:

explicitní back_insert_iterator ( Kontejner & X ) ;
back_insert_iterator & operátor = ( typové jméno Kontejner :: typ hodnoty && hodnota ) ;

Vektorový příklad:
Vektor nemá žádnou členskou funkci vložení, která by se vkládala dozadu. Nicméně členskou funkci push_back(t) lze takto vidět.

front_inserter

Vložky vepředu!
Důležité prototypy:

explicitní front_insert_iterator ( Kontejner & X ) ;
front_insert_iterator & operátor = ( typové jméno Kontejner :: typ hodnoty && hodnota ) ;

Vektorový příklad:
Vektor nemá žádnou členskou funkci vložení, která by se vkládala dopředu. Vektor také nemá členskou funkci push_front(t).

Dobrou zprávou je, že vektor má vložit členské funkce, které lze vložit kamkoli, na začátek, do nebo na konec vektoru.

vkladač

Tento iterátor by se vložil na začátek, do nebo na konec vektoru.

Důležité prototypy:

insert_iterator ( Kontejner & X, typové jméno Kontejner :: iterátor i ) ;
insert_iterator & operátor = ( typové jméno Kontejner :: typ hodnoty && hodnota ) ;

Vektorový příklad:

vektor < char > vtr { 'A' , 'B' , 'C' , 'D' , 'A' } ;
vektor < char > :: iterátor to = vtr. začít ( ) ;
to = to + 2 ;
vtr. vložit ( to, 'C' ) ;

pro ( int i = 0 ; i < vtr. velikost ( ) ; i ++ )
cout << vtr [ i ] << ',' ;
cout << endl ;

Výstup je:

A, B, c, C, D, E,

Výraz vektorového insertu je:

vtr. vložit ( to, 'C' ) ;

Vloží prvek těsně před ukazatel (to), na který ukazuje.

Přesunout iterátor

Move_iterator je také adaptér iterátoru. Následující program je podobný příkladu ve specifikaci C++:

#include
#include
#include
použitím jmenný prostor std ;

int hlavní ( )
{
seznam < char > chs { 'A' , 'B' , 'C' , 'D' , 'A' } ;
vektor < char > vtr ( make_move_iterator ( chs. začít ( ) ) , make_move_iterator ( chs. konec ( ) ) ) ;

cout << 'Původní obsah seznamu:' << endl ;
pro ( auto to = chs. začít ( ) ; to ! = chs. konec ( ) ; to ++ )
cout << * to << ',' ;
cout << endl << endl ;

cout << 'Vektorový obsah:' << endl ;
pro ( int i = 0 ; i < vtr. velikost ( ) ; i ++ )
cout << vtr [ i ] << ',' ;
cout << endl ;

vrátit se 0 ;
}

Výstup je:

Původní obsah seznamu:
A, B, C, D, E,

Vektorový obsah:
A, B, C, D, E,

Tento iterátor převede zdrojovou hodnotu na rvalue, než ji umístí do cíle.

Závěr

Hlavními iterátory v C++ jsou vstupní iterátor, výstupní iterátor, dopředný iterátor, obousměrný iterátor a iterátor s náhodným přístupem. Standardní knihovna C++ má některé šablony funkcí, které používají tyto iterátory. Vektor používá tyto iterátory prostřednictvím šablon funkcí. Vektor má pro některé z těchto iterátorů různé názvy. Existují také adaptéry iterátorů, kterými jsou: reverse_iterator, iterator adaptér a move_iterator. Existují také některé varianty iterátorů. Aby měl všechny tyto funkce, stačí zahrnout do programu. Po pochopení role těchto iterátorů, adaptérů a šablon funkcí, které je používají, se používání iterátorů s vektory stává intuitivním.