Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vector Iterators Incompatible

Tags:

c++

stl

vector

I have a class with a std::vector data member e.g.

class foo{ public:  const std::vector<int> getVec(){return myVec;} //other stuff omitted  private: std::vector<int> myVec;  }; 

Now at some part of my main code I am trying to iterate through the vector like this:

std::vector<int>::const_iterator i = myFoo.getVec().begin(); while( i != myFoo.getVec().end()) {    //do stuff    ++i; } 

The moment I reach this loop, I get the aforementioned error.

like image 449
IG83 Avatar asked Dec 07 '11 19:12

IG83


People also ask

Can we use iterator in vector?

Use an iteratorAn iterator can be generated to traverse through a vector. vector<int>::iterator iter; An iterator is used as a pointer to iterate through a sequence such as a string or vector . The pointer can then be incremented to access the next element in the sequence.

Does std :: move invalidate iterators?

For reference, std::vector::swap does not invalidate iterators.

Does pop back invalidate iterators?

So to answer your question, no it does not invalidate all iterators.


2 Answers

The reason you are getting this, is that the iterators are from two (or more) different copies of myVec. You are returning a copy of the vector with each call to myFoo.getVec(). So the iterators are incompatible.

Some solutions:

Return a const reference to the std::vector<int> :

const std::vector<int> & getVec(){return myVec;} //other stuff omitted 

Another solution, probably preferable would be to get a local copy of the vector and use this to get your iterators:

const std::vector<int> myCopy = myFoo.getVec(); std::vector<int>::const_iterator i = myCopy.begin(); while(i != myCopy.end()) {   //do stuff   ++i; } 

Also +1 for not using namespace std;

like image 73
FailedDev Avatar answered Sep 20 '22 14:09

FailedDev


You are returning a copy of the vector. Because you are returning by value - your call to begin() and end() are for completely different vectors. You need to return a const & to it.

const std::vector<int> &getVec(){return myVec;} 

I would do this slightly differently though. I'd make the class act a little like a standard container

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()) { // } 
like image 20
Adrian Cornish Avatar answered Sep 21 '22 14:09

Adrian Cornish