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.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan