【问题标题】:How to pass predicate as function parameter如何将谓词作为函数参数传递
【发布时间】:2012-01-13 07:54:35
【问题描述】:

我有一个类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 函数,以便我可以将谓词传递给它?我已经尝试了几种方法,但到目前为止都没有运气。

【问题讨论】:

  • 您可以按照建议将模板 find 包装在另一个模板中,或使用const std::function&amp; 作为谓词参数。

标签: c++ stl vector predicate std


【解决方案1】:

使用模板来获取您需要的任何类型

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) 文件中。

【讨论】:

  • 谢谢,我还没有 C++11,所以我得走模板路。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-16
相关资源
最近更新 更多