如何将谓词作为函数参数传递

How to pass predicate as function parameter

本文关键字:函数 参数传递 谓词      更新时间:2023-10-16

我有一个类CMyVector,它包含指向CMyClass对象的指针向量,我有几个"查找"函数来根据不同的标准查找元素。例如,我输入:

CMyClass* CMyVector::FindByX(int X);
CMyClass* CMyVector::FindByString(const CString& str);
CMyClass* CMyVector::FindBySomeOtherClass(CSomeOtherClass* ptr);
// Other find functions...

起初,它们被实现为循环,遍历vector,寻找与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;
}

And do:

CMyClass* CMyVector::FindByX( int x )
{
    return Find(IsSameX(x));
}

以此类推。

所以我的问题是:我应该如何声明我的Find函数,以便我可以传递我的谓词?我尝试了几种方法,但到目前为止都没有成功。

使用模板来接收你需要的任何类型

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::函数可以与所有其他实现一起存在于源文件(.cpp)中。