mattososky
asked on
erasing out of an vector...
I want to iterate through a vector, process some logic on the items determining whether they still belong in the vector. But I'm having trouble figuring out how.
While iterating through, if it's decided that vector element should be remove, you can't erase it right there, because then you cannot contiue iterating the rest of the vector. You would need to contruct a new vector and start over. I thought about saving the index of the vector item I want to remove and erasing them afterwards, but that wont work becase the the item indices will change after I remove the first one.
Any thoughts on how I can swiftly accomplish this?
While iterating through, if it's decided that vector element should be remove, you can't erase it right there, because then you cannot contiue iterating the rest of the vector. You would need to contruct a new vector and start over. I thought about saving the index of the vector item I want to remove and erasing them afterwards, but that wont work becase the the item indices will change after I remove the first one.
Any thoughts on how I can swiftly accomplish this?
Have you considered using a std::list instead? You can remove items from a list without invalidating the iterators.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Something I'll look into later, but at this point I'm commited to using the vector, so i need a solution with it.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
then would make the itr = vector.end and itr-- until it equals vector.begin?
ASKER
this isnt working...
deletes the first pass, fails at the second with 'vector iterators incompatible'
deletes the first pass, fails at the second with 'vector iterators incompatible'
vector<string*> str_vector;
for(int i = 0;i<5;i++)
{
string* s = new string("YOYO");
str_vector.push_back(s);
}
vector<string*>::iterator itr = str_vector.end();
while(itr!=str_vector.begin())
{
itr--;
str_vector.erase(itr);
}
>> then would make the itr = vector.end and itr-- until it equals vector.begin?
Traversing in reverse using forward iterators is tricky and you can't use reverse iterators to erase so you'll have to use indexes...
Traversing in reverse using forward iterators is tricky and you can't use reverse iterators to erase so you'll have to use indexes...
#include <iostream>
#include <vector>
#include <algorithm>
int gen()
{
static int i = -1;
return ++i;
}
typedef std::vector<int> intvec_t;
int main()
{
intvec_t intvec(10);
std::generate(intvec.begin(), intvec.end(), gen);
std::cout << "Display all numbers and remove odd" << std::endl;
intvec_t::size_type st = (intvec.size() - 1);
do
{
std::cout << intvec[st] << std::endl;
if(intvec[st]%2) { intvec.erase(intvec.begin() + st); }
--st;
}
while(st > 0);
std::cout << std::endl << "After all odd items were rmeoved" << std::endl;
std::copy(intvec.begin(), intvec.end(), std::ostream_iterator<int>(std::cout, "\n"));
}
>> string* s = new string("YOYO");
Why push back pointers to string, it can safely be copied into the vector? Putting heap allocated memory into vectors is always problematic... it creates very hard to protect against leakage issues with exceptions.
Why push back pointers to string, it can safely be copied into the vector? Putting heap allocated memory into vectors is always problematic... it creates very hard to protect against leakage issues with exceptions.
>>You would need to contruct a new vector and start over.
You won't need a new vector - and a little trick will help:
You won't need a new vector - and a little trick will help:
#include <vector>
#include <iostream>
using namespace std;
void main () {
int tmp[] = { 1,2,3,4,3,2,5,2};
vector<int> v(&tmp[0],&tmp[7]);
int offs = 0;
vector<int>::iterator i = v.begin();
for (i = v.begin(); i != v.end(); ++i) cout << *i << " ";
i = v.begin();
while(i != v.end()) {
if (*i == 2) { v.erase(i); i = v.begin() + offs; continue;}
++i;
++offs;
}
cout << endl;
for (i = v.begin(); i != v.end(); ++i) cout << *i << " ";
}
ASKER
this was just a test. I needed to replicate what my real application is doing. I in placeing pointers in there because this is not the only reference to these objects..