我有一个类CMyVector
,它包含一个指向CMyClass
个对象的指针向量,我有几个“查找”函数可以根据不同的标准查找元素。例如,我有:
CMyClass* CMyVector::FindByX(int X);
CMyClass* CMyVector::FindByString(const CString& str);
CMyClass* CMyVector::FindBySomeOtherClass(CSomeOtherClass* ptr);
// Other find functions...
首先,它们被实现为循环,遍历向量,寻找匹配X,str,ptr或其他的元素。所以我创建了谓词,如下所示:
class IsSameX:public unary_function<CMyClass*, bool>
{
int num;
public:
IsSameX(int n):num(n){}
bool operator()(CMyClass* obj) const
{
return (obj != NULL && (obj->X() == num));
}
};
以一堆看起来像这样的函数结束:
CMyClass* CMyVector::FindByX( int x )
{
CMyVector::iterator it = find_if(vec.begin(), vec.end(), IsSameX(x));
if (it != vec.end())
{
return *it;
}
return NULL;
}
除了被调用的谓词之外,它们看起来都一样,所以我想到了简化更多,并创建了一个像这样的函数:
CMyClass* CMyVector::Find( ThisIsWhatIDontKnow Predicate)
{
CMyVector::iterator it = find_if(vec.begin(), vec.end(), Predicate);
if (it != vec.end())
{
return *it;
}
return NULL;
}
并做:
CMyClass* CMyVector::FindByX( int x )
{
return Find(IsSameX(x));
}
等等。
所以我的问题是:我应该如何声明我的Find
函数,以便我可以将它传递给我的谓词?我尝试了几种方法,但到目前为止没有运气。
答案 0 :(得分:10)
使用模板接收您需要的任何类型
template<typename UnaryPredicate>
CMyClass* CMyVector::Find(UnaryPredicate Predicate)
{
CMyVector::iterator it = find_if(vec.begin(), vec.end(), Predicate);
if (it != vec.end())
{
return *it;
}
return NULL;
}
你也可以使用std :: function(c ++ 11)
CMyClass* CMyVector::Find(std::function<bool(const (CMYClass*)&)> Predicate)
{
CMyVector::iterator it = find_if(vec.begin(), vec.end(), Predicate);
if (it != vec.end())
{
return *it;
}
return NULL;
}
我个人更喜欢顶级的,因为编译器可能更容易优化,因为间接较少。如果调用是唯一的,则可能会内联。
编辑:还值得注意的是,如果你使用模板化选项,你将不得不在头文件中提供实现,这可能是一个痛苦。而std :: function可以与所有其他实现一起存在于源(.cpp)文件中。