Sdílet prostřednictvím


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átorX může iterovat dopředu přes sekvenci pomocí operátoru ++ a může zapsat prvek pouze jednou pomocí operátoru*.

  • Vstup. Vstupní iterátorX 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átorX 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átoruX 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átoruX. 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++