Iterátory
Iterátor je objekt, který může iterovat prvky v kontejneru standardní knihovny jazyka C++ a poskytnout přístup k jednotlivým prvkům. Kontejnery standardní knihovny C++ poskytují iterátory, aby algoritmy mohly přistupovat ke svým prvkům standardním způsobem, aniž by se museli zabývat typem kontejneru, ve které jsou prvky uloženy.
Iterátory můžete použít explicitně pomocí členských a globálních funkcí, jako jsou a end()
operátory, jako begin()
++
je a --
dozadu. Můžete také použít iterátory implicitně s smyčkou range-for nebo (pro některé typy iterátoru) operátor []
dolního indexu .
V standardní knihovně jazyka C++ je začátek sekvence nebo rozsahu prvním prvkem. Konec sekvence nebo rozsahu je vždy definován jako jeden po posledním prvku. Globální funkce begin
a end
vrácení iterátorů do zadaného kontejneru. Typická explicitní smyčka iterátoru pro všechny prvky v kontejneru vypadá takto:
vector<int> vec{ 0,1,2,3,4 };
for (auto it = begin(vec); it != end(vec); it++)
{
// Access element using dereference operator
cout << *it << " ";
}
Stejnou věc lze dosáhnout jednodušeji pomocí smyčky range-for:
for (auto num : vec)
{
// no dereference operator
cout << num << " ";
}
Existuje pět kategorií iterátorů. V pořadí zvýšení výkonu jsou kategorie:
Výstup. Výstupní iterátor
X
může iterovat dopředu přes sekvenci pomocí operátoru++
a může zapsat prvek pouze jednou pomocí operátoru*
.Vstup. Vstupní iterátor
X
může iterovat dopředu přes sekvenci pomocí operátoru++
a může číst prvek libovolný početkrát pomocí operátoru*
. Vstupní iterátory můžete porovnat pomocí==
operátorů a!=
operátorů. Po zvýšení jakékoli kopie vstupního iterátoru se žádná z ostatních kopií nedá bezpečně porovnávat, dereferencovat nebo následně zvýšit.Vpřed. Dopředný iterátor
X
může iterovat dopředu přes sekvenci pomocí operátoru ++ a může číst libovolný prvek nebo zapisovat jiné prvky než const libovolný početkrát pomocí operátoru*
. K členům elementů můžete přistupovat pomocí operátoru->
a porovnat předávané iterátory pomocí operátorů==
a!=
operátorů. Můžete vytvořit více kopií iterátoru pro předávání, z nichž každý může být nezávisle odvozen a navyšován. Předávací iterátor, který je inicializován bez odkazu na jakýkoli kontejner, se nazývá iterátor s hodnotou null. Iterátory předávání null vždy porovnávají stejné hodnoty.Obousměrný. Obousměrný iterátor může místo iterátoru
X
předat dál. Můžete však také dekrementovat obousměrný iterátor, jako v--X
,X--
nebo(V = *X--)
. K členům elementů můžete přistupovat a porovnávat obousměrné iterátory stejným způsobem jako předávané iterátory.Náhodný přístup. Iterátor náhodného přístupu může místo obousměrného iterátoru
X
. Pomocí iterátoru náhodného přístupu můžete pro přístup k prvkům použít operátor[]
dolního indexu. Operátory+
,-
+=
a-=
můžete použít k pohybu dopředu nebo dozadu zadaný počet prvků a k výpočtu vzdálenosti mezi iterátory. Obousměrné iterátory můžete porovnat pomocí ,==
,!=
<
,>
, ,<=
, a>=
.
Všechny iterátory je možné přiřadit nebo zkopírovat. Předpokládá se, že jde o odlehčené objekty a často se předávají a vrací hodnotou, nikoli odkazem. Všimněte si také, že žádná z dříve popsaných operací nemůže vyvolat výjimku při provádění platného iterátoru.
Hierarchii kategorií iterátoru lze shrnout zobrazením tří sekvencí. Pro přístup jen pro zápis do sekvence můžete použít některou z těchto možností:
výstupní iterátor
-> dopředný iterátor
-> obousměrný iterátor
–> iterátor náhodného přístupu
Šipka vpravo znamená, že "lze nahradit". Jakýkoli algoritmus, který volá výstupní iterátor, by měl dobře fungovat s iterátorem předávání, například, ale ne naopak.
Pro přístup jen pro čtení ke sekvenci můžete použít některou z těchto možností:
vstupní iterátor
-> dopředný iterátor
-> obousměrný iterátor
–> iterátor náhodného přístupu
Vstupní iterátor je v tomto případě nejslabší ze všech kategorií.
Nakonec pro přístup ke čtení a zápisu do sekvence můžete použít některou z těchto možností:
přeposlání iterátoru
-> obousměrný iterátor
–> iterátor náhodného přístupu
Ukazatel objektu může vždy sloužit jako iterátor s náhodným přístupem, takže může sloužit jako libovolná kategorie iterátoru, pokud podporuje správný přístup pro čtení a zápis do sekvence, která určuje.
Iterátor Iterator
jiný než ukazatel objektu musí také definovat typy členů vyžadované specializacem iterator_traits<Iterator>
. Tyto požadavky lze splnit odvozením Iterator
z iterátoru veřejné základní třídy.
Je důležité pochopit přísliby a omezení jednotlivých kategorií iterátoru, abyste zjistili, jak jsou iterátory používány kontejnery a algoritmy ve standardní knihovně jazyka C++.
Poznámka:
Můžete se vyhnout použití iterátorů explicitně pomocí smyčky range-for. Další informace najdete v tématu Příkaz založený na rozsahu.
Microsoft C++ teď nabízí kontrolované iterátory a ladicí iterátory, abyste zajistili, že nepřepíšete hranice kontejneru. Další informace najdete v tématu Kontrola iterátorů a podpora ladění iterátoru.
Viz také
Standardní knihovna C++ – referenční dokumentace
Bezpečný přístup z více vláken ve standardní knihovně C++