The snippet below works. However, it’s a bit ugly because it uses a static method to wrap a method call to a predicate.
In other words, I would like to replace:
c.remove_if_true( Value::IsOdd ); // static method
with something like
c.remove_if_true( Value::isOdd ); // member method
There should be one fewer level of indirection and hopefully, the resultant code would be clearer.
How do I refactor my code to call isOdd() directly without having to go through a static method wrapper?
However, if this implementation is as clear as I can make this code, also let me know. TIA.
#include <vector>
#include <functional>
template< typename T >
class MyContainer
{
public:
typedef std::function<bool(const T& t)> PREDICATE;
public:
void remove_if_true( PREDICATE predicate )
{
// NOTE: use implementation from KennyTM's answer below
}
private:
std::vector< T > m_vec;
};
class Value
{
public:
Value( int i ) : m_i( i ) { }
bool isOdd() const { return m_i%2==1; }
static bool IsOdd( const Value& v ) { return v.isOdd(); }
private:
int m_i;
};
int main()
{
MyContainer<Value> c;
c.remove_if_true( Value::IsOdd ); // would like to replace with Value::isOdd here
}
Solution using KennyTM’s Answer
ataylor’s suggestion std::mem_fun_ref() required with gcc 4.6.1 and other compilers not completely up-to-date with latest standards
#include <vector>
#include <algorithm>
#include <functional>
template< typename T >
class MyContainer
{
public:
typedef std::const_mem_fun_ref_t<bool, T> PREDICATE;
public:
void remove_if( PREDICATE predicate )
{
auto old_end = m_vec.end();
auto new_end = std::remove_if(m_vec.begin(), old_end, predicate);
m_vec.erase(new_end, old_end);
}
private:
std::vector< T > m_vec;
};
class Value
{
public:
Value( int i ) : m_i( i ) { }
bool isOdd() const { return m_i%2==1; }
private:
int m_i;
};
int main()
{
MyContainer<Value> c;
c.remove_if( std::mem_fun_ref( &Value::isOdd ));
}
BTW, is there any reason you need to avoid
std::remove_if?