Поток управления с помощью итераторов

0

Вопрос

Скажем, у меня есть что-то вроде этого:

void myFunk(std::vector<T>& v, std::vector<T>::iterator first, std::vector<T>::iterator last) {
    while (first != last) {
        if ((*first) > (*last)) {
            T someT;
            v.push_back(someT);
        }
        first++;
    }
}

int main(){
    std::vector<T> foo = {some, T, values};
    myFunky(foo, foo.begin(), foo.end())
    return 0;
}

Приведет ли это к бесконечному циклу или он закончится после foo.size() итерации? Другими словами, будет ли last итератор будет обновлен как foo вырос, или он сохранит значение, заданное в вызове функции?

Я предполагаю, что last изменилось бы, так как это указатель на позицию, но хотелось бы получить какое-то подтверждение.

c++ controls flow iterator
2021-11-18 16:56:38
1

Лучший ответ

0

Приведет ли это к бесконечному циклу или он закончится после foo.size() итерации?

Ни. То, что вы делаете, является неопределенным поведением по нескольким причинам:

  • Вы изменяете vector во время итерации по нему.

    Если вектор перераспределяет свою внутреннюю память при перемещении нового элемента, все существующие итераторы в vector являются недействительными, включая оба итератора, с которыми вы используете цикл. Но даже простое нажатие на новый элемент всегда делает недействительным end() по крайней мере, итератор.

    См. раздел Правила признания итератора недействительным для контейнеров C++

  • Вы разыменовываете end() итератор, который никогда не ссылается на допустимый элемент.

Я предполагаю, что last изменится, так как это указатель на позицию

Это не может измениться, так как вы передали это в myFunc функция по значению, поэтому она является копией оригинала end() итератор. Если end() изменяет значение, last значение не изменится, так как это копия.

В любом случае итераторы не обязательно реализуются как указатели, но указатели являются допустимыми итераторами. Но в данном случае это не имеет значения. Даже если vector::iterator были всего лишь простым указателем, last все равно будет аннулироваться при каждом нажатии/перераспределении.

2021-11-18 21:20:33

Передача значения была преднамеренной - идея состояла в том, чтобы попытаться заставить вектор повторяться в текущих значениях, добавляя новые в конце. Имеет смысл, что я получал нарушения доступа к памяти во время выполнения. Спасибо за плагин правил недействительности (я знал, что то, что я искал, было задокументировано, но не знал, как это выразить словами). И спасибо за ответ, чувак. Действительно все прояснилось. Ура!
Pedro Barbeira

Я бы предложил кэшировать вставки в локальный вектор, а затем добавить их в конец целевого вектора после завершения итерации.
Remy Lebeau

На других языках

Эта страница на других языках

Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................