Векторные итераторы Несовместимые
У меня есть класс с элементом данных std::vector, например.
class foo{
public:
const std::vector<int> getVec(){return myVec;} //other stuff omitted
private:
std::vector<int> myVec;
};
Теперь в какой-то части моего основного кода я пытаюсь выполнить итерацию через вектор следующим образом:
std::vector<int>::const_iterator i = myFoo.getVec().begin();
while( i != myFoo.getVec().end())
{
//do stuff
++i;
}
В тот момент, когда я достигаю этого цикла, я получаю вышеупомянутую ошибку.
Ответы
Ответ 1
Причина, по которой вы получаете это, состоит в том, что итераторы состоят из двух (или более) разных копий myVec. Вы возвращаете копию вектора при каждом вызове myFoo.getVec()
. Таким образом, итераторы несовместимы.
Некоторые решения:
Верните ссылку const на std::vector<int>
:
const std::vector<int> & getVec(){return myVec;} //other stuff omitted
Еще одно решение, вероятно, предпочтительнее было бы получить локальную копию вектора и использовать его для получения ваших итераторов:
const std::vector<int> myCopy = myFoo.getVec();
std::vector<int>::const_iterator i = myCopy.begin();
while(i != myCopy.end())
{
//do stuff
++i;
}
Также +1 для не using namespace std;
Ответ 2
Вы возвращаете копию вектора. Поскольку вы возвращаетесь по значению - ваш вызов begin() и end() для совершенно разных векторов. Вам нужно вернуть константу и ей.
const std::vector<int> &getVec(){return myVec;}
Я бы сделал это несколько иначе. Я бы сделал действие класса немного похожим на стандартный контейнер
class Data
{
public:
typedef std::vector<int>::const_iterator const_iterator;
const_iterator begin() const { return myVec.begin(); }
const_iterator end() const { return myVec.end(); }
};
Data::const_iterator i=myFoo.begin();
while(i != myFoo.end())
{
//
}
Ответ 3
Другая причина утверждения отладки MSVC STL "векторные итераторы несовместимы" работает на недействительном итераторе.
т.е. v.erase(i)
, а затем сравните i != v.end()
стирание делает недействительными i
и поэтому не может использоваться при сравнении.
Ответ 4
Проблема в том, что вы всегда возвращаете другую копию вектора. Используйте ссылку:
const std::vector<int>& getVec(){return myVec;} //other stuff omitted
Ответ 5
ну, я не думаю, что копия вектора могла быть единственной причиной, которая кажется мне слишком позаботиться.
в моем случае я просто обнаружил, что поврежденный стек, куча, необусловленные изменения также могут привести к этому сбою, и это на самом деле скрывает основную причину. в моем случае я изменил использование индексатора для повторения и поиска основной причины.
Ответ 6
Еще одна причина, по которой это утверждение может вызвать, заключается в том, что вы бы выделили "foo" с помощью "malloc" вместо "new", эффективно пропустив конструктор (ы).
Это вряд ли произойдет с проектом, разработанным с нуля на С++, но при преобразовании простого кода C в С++ (заменяя статический массив [] в некоторой структуре на stl-вектор), вы можете просто не понимать, что динамические экземпляры указанная структура (и элементы внутри) не будет иметь свой конструктор, но если вы также измените "malloc" на "новый".
Ответ 7
Вы делаете постоянную копию вектора-члена, не обращаетесь к вектору-члену.
Измените это:
const std::vector<int> getVec(){return myVec;} //other stuff omitted
:
const std::vector<int> & getVec(){return myVec;} //other stuff omitted
Чтобы пройти немного глубже, итератор, который вы получите из этого утверждения:
std::vector<int>::const_iterator i = myFoo.getVec().begin();
- это итератор к временной копии вашего вектора, который исчезает после выполнения этого оператора, недействительным итератором.
Ответ 8
Изменить
const std::vector<int> getVec(){return myVec;}
к
const std::vector<int>& getVec(){return myVec;}
Ответ 9
Ваша функция getVec() возвращает глубокую копию вектора-члена, поэтому два вызова getVec(), которые вы делаете для получения итераторов, получают итераторы в разных контейнерах. То есть вы не можете достичь getVec(). End() из отдельного getVec(). Begin() iterator без вызова поведения undefined.
Вы можете решить это двумя способами:
1) Получите getVec ссылку на const (то есть const std::vector &) (предпочтительно) или...
2) Замените два вызова getVec() одним и сохраните результат в переменной std::vector. Затем используйте эту переменную для обоих вызовов для begin() и end(). Например:
std::vector<int> v = myFoo.getVec();
std::vector<int>::const_iterator b = v.begin();
std::vector<int>::const_iterator e = v.end();
Ответ 10
Поскольку вы возвращаетесь по значению - ваш вызов begin() и end() для совершенно разных векторов. Вам нужно вернуть константу и ей