std::vector
итераторы могут быть реализованы как указатели. Следствием является то, что если вы добавите элементы в вектор, выдающиеся итераторы, очевидно, станут недействительными, потому что в общем случае векторные данные должны быть перераспределены.Неверные векторные итераторы
Первое предположение относительно точных правил заключается в том, что разрешенные операции точно такие же, как и для указателей, например. не разыгрывайте недействительный итератор до тех пор, пока оно не будет переназначено допустимым значением, но это, похоже, не совсем верно, потому что реализация Microsoft в режиме отладки иногда вызывает исключение, если вы, например. вычесть векторные итераторы, указывающие на разные блоки данных (что полезно для отладки, если быть уверенным).
Является ли добавление к указателю правил чем-то вроде «не вычитать итераторы для разных блоков данных» или «не выполнять арифметику на недействительном итераторе до тех пор, пока оно не будет переназначено действительным значением» или что-то еще?
Например, действительна ли следующая программа (которая работает как на Microsoft C++, так и на GCC)?
#include <algorithm>
#include <iostream>
#include <vector>
using std::cout;
using std::ostream;
using std::vector;
template<class T> ostream& operator<<(ostream& os, vector<T>& v) {
os << '[';
bool c = 0;
for (auto a: v) {
if (c)
os << ", ";
c = 1;
os << a;
}
return os << ']';
}
void f(vector<int>& v, vector<int>::iterator& i) {
*i = 10;
for (int j = 0; j < 10; j++)
v.insert(begin(v), j);
i = begin(v)+5;
}
int main() {
vector<int> v;
for (int i = 0; i < 10; i++)
v.push_back(i);
auto i = begin(v)+5;
f(v, i);
i[1] = 11;
cout << v << '\n';
return 0;
}
Что именно вы подразумеваете под «итераторами, указывающими на разные блоки данных»? – jogojapan
И почему пример программы недействителен? В какой момент происходит что-то, что вы считаете недействительным? – jogojapan
@jogojapan разные векторы или элементы одного и того же вектора до и после добавления новых элементов вызвали перераспределение. – rwallace