Niedawno dowiedziałem się o właściwym sposobie pracy z odwrotnymi iteratorami w C++ (szczególnie, gdy trzeba je usunąć). (Patrz this question i this one.)Używaj zwykłego iteratora do iteracji wstecznej lub zmagań z reverse_iterator?
ten sposób jesteś ma to zrobić:
typedef std::vector<int> IV;
for (IV::reverse_iterator rit = iv.rbegin(), rend = iv.rend();
rit != rend; ++rit)
{
// Use 'rit' if a reverse_iterator is good enough, e.g.,
*rit += 10;
// Use (rit + 1).base() if you need a regular iterator e.g.,
iv.erase((rit + 1).base());
}
Ale
myślę
, że to jest o wiele lepsza (nie rób tego, a nie normy Wymaganie jest spełnione, jak MooingDuck zwraca uwagę)
for (IV::iterator it = iv.end(), begin = iv.begin();
it-- != begin;)
{
// Use 'it' for anything you want
*it += 10;
iv.erase(it);
}
Wady:
-
Powiedz mi. Co jest nie tak z tym? - Nie jest zgodny ze standardami, jak wskazuje MooingDuck. To prawie unieważnia każdą z możliwych zalet poniżej.
Plusy:
- Wykorzystuje znajome idiom na odwrocie for-pętle
- Nie trzeba pamiętać (lub wyjaśnienie) w
+1
- mniej pisania
- Works dla std : lista też:
it = il.erase(it);
- Po usunięciu elementu nie trzeba dostosowywać iteratora
- Jeśli wymazać, nie trzeba ponownie obliczyć iterator rozpocząć
Masz na myśli, oprócz tego, że jest to niezdefiniowane zachowanie i zawiedzie/zawiesi się w typowych sytuacjach? Wypróbuj za pomocą pustej 'mapy'. –
dbać o opracowanie w odpowiedzi? Czy UB dekrementuje iterator wejściowy lub dekrementujący poza początkiem? Czy to UB dla wszystkich pojemników? – Dan
Nie można zmniejszyć wartości iteratora wejściowego lub wyjściowego (zapomniałem o tym, dobre oko), a także nie można zmniejszyć wartości początkowej dla żadnego kontenera. –