Hi, can someone explain to me how the member function vector::erase(iter) works? The tutorial says this function erases the entry to which iter points, and return the iterator of the next entry after the one being deleted. I want to know how this function actually works. Doesn't it just simply assign very entry starting from iter with the value of their next entry? If so, I suppose I can use the following to cout the next entry after the one being deleted. But it turned out I was wrong. So I guess when I deleted an entry from a vector, the address of the entries of that vector are not consecutive anymore. Is it right?
1 2 3 4 5 6
std::vector<double> dVec(10);
for(std::vector<double>::size_type i=0; i<dVec.size(); ++i)
dVec[i]=i;
std::vector<double>::iterator iter=dVec.begin();
dVec.erase(iter); // if I use iter=dVec.erase(iter), I get the expected result
std::cout<<*iter<<std::endl;
Thank you, Kbw! It is indeed helpful. But I'm still confused. The following code shows that the iter actually has the same address as it had before the deletion...
(P.S. It's wierd that the compiler of VS2012 complains about the issue described in the code below, while the compiler of this website doesn't...)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
#include <iostream>
#include <vector>
int main()
{
usingnamespace std;
vector<double> dVec(10);
for(vector<double>::size_type i=0; i<dVec.size(); ++i)
dVec[i]=i;
vector<double>::iterator itBeg=dVec.begin(), iter=itBeg+2;
cout<<distance(itBeg, iter)<<endl; // distance between itBeg and iter is 2
iter=dVec.erase(iter); /* if I call dVec.erase(iter) without assigning to iter,
the compiler complains about the line below*/
cout<<distance(itBeg, iter)<<endl; // note that itBeg remains intact
return 0;
}
Erase returns iterator to the element after last deleted. As remaining elements gets shifted to position occupied by deleted, you will get iterator to the element with same indes.
Thanks MiiNiPaa. This is exactly the point I'm confused about. Now that all remaining entries are shifted backward for one step, why don't we just keep the iterator pointing to the entry being deleted. Why do we prefer receiving the return value of vector::erase(), since the value of that iterator essentially doesn't change at all.
Why do we prefer receiving the return value of vector::erase(), since the value of that iterator essentially doesn't change at all.
Because standard says that iterators at the point of deletion and after are invalidated. Iterator can store more than just pointer to value and deletion of array element can disrupt something inside.
Can I consider this convention as a strategy to avoid mistakes in some complicated situations?
Well, it is used to avoid undefined behavior which would be caused by using invalidated iterator.
If standard says that something is invalidated or should not be used, do not use it. No matter how logical you reasonong sounds or how it is makes no sense to not work, do not do something prohibited by language standard. This way you will avoid many problems.