如何重构容器以直接使用谓词方法
how can I refactor a container to use a predicate method directly?
下面的代码段有效。然而,它有点难看,因为它使用静态方法来包装对谓词的方法调用。
换句话说,我想取代:
c.remove_if_true( Value::IsOdd ); // static method
像
c.remove_if_true( Value::isOdd ); // member method
应该减少一个间接级别,希望得到的代码会更清晰。
如何重构代码以直接调用isOdd()
,而不必经过静态方法包装
但是,如果这个实现尽我所能清楚地编写这个代码,也请告诉我。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
}
使用KennyTM答案的解决方案
ataylor的建议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 ));
}
c.remove_if_true( std::mem_fn(&Value::isOdd) );
顺便说一句,你有什么理由需要避开std::remove_if
吗?
void remove_if_true(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);
}
c.remove_if_true( std::bind( &Value::isOdd, _1 ) );
您可以使用std::mem_fn_ref
包装isOdd
:
c.remove_if_true( std::mem_fun_ref(&Value::isOdd) );
使用lambdas的最佳方式:
c.remove_if_true( [] (const Value & v) { return v.get() % 2 == 0; } );
或更多自我评价:
auto isOdd = [] (const Value & v) { return v.get() % 2 == 0; };
c.remove_if_true( isOdd );
相关文章:
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 通过方法访问结构
- 最小硬币更换问题(自上而下方法)
- C++为构建时间获取QDateTime的可靠方法
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 处理多个异常集合的C++方法
- std::condition_variable::wait()如何评估给定的谓词
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 有什么方法可以遍历结构吗
- 当类在C++中定义时,有什么方法可以"register"类吗?
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- 使用std::函数映射对象方法
- 有符号的int和int-有没有一种方法可以在C++中区分它们
- 我实现谓词的方法有什么问题
- 是否有使用谓词比较两个范围的标准方法
- 替换由谓词确定的 std::string 中的字符的最 stl-ish 方法是什么
- 如何重构容器以直接使用谓词方法
- 如何在c++中重载接受谓词vs值的方法
- 根据谓词从std向量中删除元素的有效方法