Public Group

This topic is 4955 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I was wondering, if I use a function to retreive a value for the for function, will it be retreieved every loop, or is it just retreived at the beggining?
for(int x; x < Variable.GetValue(); x++)

Basically, I want to go through a vector and do some stuff to its variables, and if it returns 1, the specific element would be deleted. In this scenario, the size of the vector should decrease and the loop should be done one less time. Hence, that's why the retreived value needs to be updated every loop.
//Vector is a vector of pointers
for(int x = 0; x < Vector.size(); x++)
if(Vector[x]->Animate(Time)) //if returns 1, delete it
{
delete Vector[x];
Vector.erase(Vector.begin()+x);
}


I've actually gone and tested it out and it doesn't get me any errors, so I think I'm fine. Thanks!

##### Share on other sites
its evaluated every iteration. just fyi:

for( initializations; conditions; loop operation )
{...}

In the 'for' construct, only initialization occurs ONCE. All others occur for each iteration. So watever u put in condition will be evaluated each round irrespective if its a function or variable. Hope that helps.

##### Share on other sites
I could be wrong, but I'm not sure if that'll erase the whole vector if they all return 1. Problem is that x is increasing while the vector is decreasing:

Vector: { 0, 1, 2, 3, 4, 5 }

X = 0 so we delete Vector[0]

Vector: { 1, 2, 3, 4, 5 }

X = 1 so we delete Vector[1]

Vector: { 1, 3, 4, 5 }

X= 3 so we delete Vector[2]

Vector: { 1, 3, 5 }

X = 4 which is bigger than the Vector's size.

Can you see what I mean?

Things will really get messy anytime there are two deletions needed in a row since the next one will take the previous one's place, while the index will still be incremented.

If I'm making any sense (again, I could be wrong), you should be able to decrement x anytime you delete something and be fine.

##### Share on other sites
You're not wrong, just in case you were curious. It is indeed skipping elements.

##### Share on other sites
ah, yes, I was afraid of that...

so putting x-- in the delete section should fix the issue, right?

##### Share on other sites
Yeah, just make sure you only decrement when you delete and it should work fine.

##### Share on other sites
std::vector<whatever*>::iterator itor = Vector.begin();while(itor != Vector.end()){   if((*itor)->Animate(Time))   {      delete *itor;      itor = Vector.erase(itor);   }   else ++itor;}

Or even

#include <functional>#include <algorithm>struct AnimateAndDeleteIfDead :   std::unary_function<whatever*, bool>{   some_time_type t_;   AnimateAndDeleteIfDead(some_time_type t) : t_(t) {}   bool operator()(whatever* ptr)   {      bool dead = ptr->Animate(t);      if(dead) delete ptr;      return dead;   }};...std::vector<whatever*>::iterator garbage;garbage = std::remove_if( Vector.begin(), Vector.end(),                          AnimateAndDeleteIfDead(Time) );Vector.erase(garbage, Vector.end());

##### Share on other sites
Or, if you're really into generic code

#include <cstdlib>#include <functional>#include <algorithm>#include <iostream>#include <vector>template<class Itor, class Pred, class Func>Itor remove_if_cleanup( Itor first, Itor last, Pred pred, Func cleanup){   Itor write = first;   while(first != last)   {      if( pred(*first) )      {          cleanup(*first);          *write = *first;          ++write;      }      ++first;   }   return write;}template<class T>struct delete_ptr :   std::unary_function<T*, void>{   void operator()(T* ptr) const { delete ptr; }};struct whatever{   bool Animate(int time) { return time % 2; }   ~whatever() { std::cout << "deleted" << std::endl; }};int main(){   std::vector<whatever*> vec;   for(int i = 0; i < 30; ++i) vec.push_back(new whatever);   int time = 1;   std::vector<whatever*>::iterator garbage;   garbage = remove_if_cleanup( vec.begin(), vec.end(),                                std::bind2nd                                (                                   std::mem_fun(&whatever::Animate),                                   time                                 ),                                delete_ptr<whatever>()                               );   vec.erase( garbage, vec.end() );}

Or you can take a leaf from std::bind2nd and write your own functor combiner

#include <cstdlib>#include <functional>#include <algorithm>#include <iostream>#include <vector>template<class Pred, class Func>struct caller_if :   std::unary_function< typename Pred::argument_type,                        typename Pred::result_type >{   Pred pred_;   Func func_;   caller_if( Pred pred, Func func ) :      pred_(pred),      func_(func)   {}   typename Pred::result_type operator()( typename Pred::argument_type arg )   {      bool test = pred_(arg);      if(test) func_(arg);      return test;   }};template<class Pred, class Func>caller_if<Pred,Func> call_if( Pred pred, Func func ){   return caller_if<Pred,Func>(pred, func);}template<class T>struct delete_ptr :   std::unary_function<T*, void>{   void operator()(T* ptr) const { delete ptr; }};struct whatever{   bool Animate(int time) { return time % 2; }   ~whatever() { std::cout << "deleted" << std::endl; }};int main(){   std::vector<whatever*> vec;   for(int i = 0; i < 30; ++i) vec.push_back(new whatever);   int time = 1;   std::vector<whatever*>::iterator garbage;   garbage = remove_if( vec.begin(), vec.end(),                        call_if                        (                            std::bind2nd                           (                               std::mem_fun(&whatever::Animate),                              time                           ),                           delete_ptr<whatever>()                        )                      );   vec.erase( garbage, vec.end() );}

Or you may pull in the Boost Lambda library

#include <algorithm>#include <iostream>#include <vector>#include <boost/lambda/lambda.hpp>#include <boost/lambda/bind.hpp>#include <boost/lambda/if.hpp>#include <boost/lambda/construct.hpp>using namespace boost::lambda;struct whatever{   bool Animate(int time) { return time % 2; }   ~whatever() { std::cout << "deleted" << std::endl; }};int main(){   std::vector<whatever*> vec;   for(int i = 0; i < 30; ++i) vec.push_back(new whatever);   int time = 1;   bool dead;   std::vector<whatever*>::iterator garbage;   garbage = remove_if( vec.begin(), vec.end(),                        (                           var(dead) = bind( &whatever::Animate, _1, time ),                           if_( dead )                           [                              bind(delete_ptr(),_1)                           ],                           dead                        )                      );   vec.erase( garbage, vec.end() );}

At which point you might decide to just kill me, because if you had just used a container of smart pointers, no manual deletion would have been needed:

  GNU nano 1.3.4                                            File: foo.cc#include <algorithm>#include <iostream>#include <vector>#include <boost/bind.hpp>#include <boost/shared_ptr.hpp>using namespace boost;struct whatever{   bool Animate(int time) { return time % 2; }   ~whatever() { std::cout << "deleted" << std::endl; }};int main(){   typedef shared_ptr<whatever> sp_whatever;   std::vector<sp_whatever> vec;   for(int i = 0; i < 30; ++i) vec.push_back( sp_whatever(new whatever));   int time = 1;   std::vector<sp_whatever>::iterator garbage;   garbage = remove_if( vec.begin(), vec.end(), bind( &whatever::Animate, _1, time ) );   vec.erase( garbage, vec.end() );}

Have fun.

##### Share on other sites
...ok that was nuts. ;)

##### Share on other sites
Quote:
 Original post by Krisc...ok that was nuts. ;)

I second that.

1. 1
Rutin
67
2. 2
3. 3
4. 4
5. 5

• 21
• 10
• 33
• 20
• 9
• ### Forum Statistics

• Total Topics
633420
• Total Posts
3011793
• ### Who's Online (See full list)

There are no registered users currently online

×

## Important Information

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!