vectors: rend () аннулируется функцией erase ()

Согласно спецификации C ++ (23.2.4.3), vector :: erase () делает недействительными только» все итераторы и ссылки после точки стирания "

Таким образом, при использовании reverse_iterator для передачи всех элементов вектора стирание текущего итератора должно , а не приводить к тому, что член 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 увеличивается.

Кто-нибудь, пожалуйста, может объяснить такое поведение?

Спасибо.

РЕДАКТИРОВАТЬ

Я думаю, что этот пример кода лучше показывает, что проблема не с 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());
}

И ошибки, связанные с несовместимостью векторных итераторов в цикле for при входе после стирания.

5
задан Mahmoud Al-Qudsi 8 March 2011 в 17:48
поделиться