Фрагмент ниже работает. Тем не менее, это немного уродливо, потому что он использует статический метод для переноса вызова метода в предикат.
Другими словами, я хотел бы заменить:
c.remove_if_true( Value::IsOdd ); // static method
с чем-то вроде
c.remove_if_true( Value::isOdd ); // member method
Должен быть один уровень косвенности, и, надеюсь, результирующий код будет более понятным.
Как мне реорганизовать мой код для прямого вызова isOdd()
без необходимости проходить через обертку статического метода?
Однако, если эта реализация настолько ясна, насколько я могу сделать этот код, также дайте мне знать. ТИА.
#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
}
Решение с использованием ответа KennyTM
предложение атайлора std::mem_fun_ref()
требуется с gcc 4.6.1 и другими компиляторами, которые не полностью соответствуют последним стандартам
#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 ));
}