Как сохранить разыменование итератора при добавлении его вектора? - PullRequest
1 голос
/ 07 декабря 2010

Допустим, у меня есть этот код:

std::vector<Object*> objects;
std::vector<Object*>::iterator iter;
for (iter = objects.begin(); iter != objects.end(); iter++) {
    if (condition)
        objects.push_back(new Object());
}

Однако, когда происходит push_back, iter становится недопустимымБез сброса iter как мне сделать его разыменованным?Если мне нужно сбросить его, есть ли простой способ сделать это, чтобы он вернулся туда, где он был раньше?

Ответы [ 6 ]

5 голосов
/ 07 декабря 2010

Я бы порекомендовал вам просто получить доступ к нему по индексу. Это полностью устраняет проблему.

1 голос
/ 07 декабря 2010

Если вам абсолютно необходимо использовать итераторы для этого:

std::vector<Object*> objects;
std::vector<Object*> newObjects;
std::vector<Object*>::iterator iter;
for (iter = objects.begin(); iter != objects.end(); ++iter)
{
    if (condition)
    {
        newObjects.push_back(new Object());
    }
}

std::copy(newObjects.begin(), newObjects.end(), back_inserter<vector<Object*> >(objects));
0 голосов
/ 08 декабря 2010

Как уже сказано в большинстве других ответов, вам, вероятно, лучше получить доступ к вектору по индексу в этом случае.

Однако для полноты: std::list у итераторов нет этой "проблемы".Так что использование list вместо vector является возможным решением.

0 голосов
/ 07 декабря 2010

§23.1 / 11:

Если не указано иное (явно или путем определения функции в терминах других функций), вызов функции-члена контейнера или передача контейнера в качестве аргумента в библиотекуфункция не должна делать недействительными итераторы или изменять значения объектов в этом контейнере.

Однако, прямо не указано, что std :: vector :: push_back делает недействительными любые итераторы.

0 голосов
/ 07 декабря 2010

Итератор становится недействительным только в том случае, если вектор должен перераспределить больше памяти.

Чтобы предотвратить перераспределение памяти, предварительно выделите всю память, которая вам нужна, с помощью Reserve () (при условии, что вы знаете этот размер при выделениивектор).

Более простое решение - сохранить косвенную ссылку на член (индекс в массиве).

0 голосов
/ 07 декабря 2010

Вы должны привести к старомодному циклу for с числовыми индексами.Либо так, либо резервируем () вектор до запуска цикла, чтобы гарантировать, что он не изменится.

Кроме того, необработанные указатели?Srsly.

...