I'm playing around with creating a very simple particle generator. Yet I find that when I store these particles in a vector I'm having issues accessing them and iterating through them.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
//If Vector has < 100 elements push back new particle with a random velocity.
if(pVect.size() < 100)
{
Particle p(partRadius, winWidth/2, (winHeight - partRadius));
p.setVelocity(rX, rY);
pVect.push_back(p);
}
//Cycle through all elements in pVect and update the position and display the particle.
for(std::vector<Particle>::iterator i; i != pVect.end(); ++i)
{
pVect[i].update();
window.draw(pVect[i].getShape());
}
But when I try to cycle through the elements I get an error on what is line 14 here.;
no match for 'operator[]' (operand types are 'std::vector<Particle>' and 'std::vector<Particle>::iterator {aka __gnu_cxx::__normal_iterator<Particle*, std::vector<Particle> >}')
for (auto& i : pVect)
{
int tAlpha = i.getAlpha();
i.setAlpha(tAlpha - 5);
i.update();
window.draw(i.getShape());
}
But then how do I erase an element if I need to?
Say I wanted to delete elements based off of their alpha value...
1 2 3 4 5 6 7 8 9 10 11 12
for (auto& i : pVect)
{
int tAlpha = i.getAlpha();
i.setAlpha(tAlpha - 5);
i.update();
window.draw(i.getShape());
if (i.getAlpha() == 0)
{
pVect.erase(pVect.begin() + i); // obviously not correct because i is not an iterator.
}
}
Well since i is not an integral type you can't use it as an index. Don't forget that an iterator is basically a pointer. Have you just tried to update and draw using the iterator?
Yes, I can get it to work fine using the ranged for, but I can't for the life of me think of how I'd delete an element if I do it that way. What I don't understand is why I can't iterate using []. i is a std::vector<Particle>::iterator. The error says that's what [] requires.
no match for 'operator[]' (operand types are 'std::vector<Particle>' and 'std::vector<Particle>::iterator {aka __gnu_cxx::__normal_iterator<Particle*, std::vector<Particle> >}')
You can't pass an std::vector<T>::iterator to std::vector<T>::operator[](). An iterator is analogous to a pointer. You wouldn't expect this to work, would you?
1 2 3
int array[] = {1, 2, 3, 4];
int *i = array + 2;
array[i] = 42;
You have to dereference the iterator to access the element of the container, like I did in my previous post:
1 2 3 4
for(std::vector<Particle>::iterator i; i != pVect.end(); ++i){
i->update;
window.draw(i->getShape());
}
Also, generally you should not remove or add elements to a container while you're iterating it. std::vector in particular invalidates iterators on std::vector::erase(). If the vector reallocates while you're iterating it your program will crash if you're lucky, and it will do weird things if you're unlucky.