Согласно спецификации C ++ (23.2.4.3), vector :: erase () делает недействительными только «все итераторы и ссылки после точки стирания»
Таким образом, при использовании reverse_iterators для передачи по всем элементам вектора удаление на текущем итераторе должно не приводить к тому, что член rend () становится недействительным.
Этот код будет работать под G ++, но обеспечит исключение времени выполнения в Windows (VS2010):
#include <vector>
using namespace std;
int main()
{
vector<int> x;
x.push_back(1);
x.push_back(2);
x.push_back(3);
//Print
for(vector<int>::const_iterator i = x.begin(); i != x.end(); ++i)
printf("%d\n", *i);
//Delete second node
for(vector<int>::reverse_iterator r = x.rbegin(); r != x.rend(); ++r)
if(*r == 2)
x.erase((r+1).base());
//Print
for(vector<int>::const_iterator i = x.begin(); i != x.end(); ++i)
printf("%d\n", *i);
return 0;
}
Интересна ошибка:
Выражение: векторный итератор не может быть уменьшен
Задано в строке второго цикла for при втором запуске. Уменьшение относится к внутреннему «текущему» элементу итератора reverse_iterator, который уменьшается при каждом увеличении reverse_iterator.
Может кто-нибудь объяснить это поведение, пожалуйста?
Спасибо.
EDIT
Мне кажется, этот пример кода лучше показывает, что проблема не в r, а в rend ():
//Delete second node
for(vector<int>::reverse_iterator r = x.rbegin(); r != x.rend();)
{
vector<int>::reverse_iterator temp = r++;
if(*temp == 2)
x.erase((temp+1).base());
}
И ошибки с vector iterators incompatible
в цикле for при входе после стирания.