理解find_if谓词

时间:2013-09-09 00:14:41

标签: predicate c++

我正在阅读下面的例子,这是我从另一篇SO帖子中得到的。例子是这样的

class checker 
{ 
public:  
    bool operator()(unsigned int i)  
    { 
     if (i%2 == 0)
     {
         return true;   --------------->Statement A
     }
     return false;

    }  
}; 

    std::vector<int> vec;
    vec.push_back(3);
    vec.push_back(5);
    vec.push_back(2);
    if(std::find_if(vec.begin(), vec.end(), checker()) != vec.end())
    {
        std::cout << "Found";
    }

现在我对上面的例子有三个问题:

Q1- find_if的第3个参数接受谓词。这里我使用的是仿函数对象。该谓词是指针(地址)还是对象。在这里,我传递一个对象但是在这个例子中msdn传递了一个地址。我在那个例子中意识到谓词不是类的成员方法。但是,如果有人可以在这里澄清谓词参数的要求,我仍然会感激。因为如果它可以接受函数指针,那么这不起作用

bool (checker::*aptr)(unsigned int) = NULL;  //Function ptr of class method
aptr = &(checker::operator());
    if(std::find_if(vec.begin(), vec.end(), aptr) != vec.end()){...};

Q2-虽然上面的例子工作正常但是当我在语句A处设置断点时,断点永远不会得到命中,并且假设它返回true。澄清这一点会有所帮助。

Q3-一些例子从std::unary_function<key_struct, bool>派生了结构/类,原因是什么。上面的课程适合我。为什么需要从std::unary_function<key_struct, bool>中获取它?

1 个答案:

答案 0 :(得分:1)

  1. 谓词参数可以是任何可以像具有相应参数的函数一样调用并返回可转换为bool的东西。它可以是函数对象,即具有函数调用操作符的类的对象,或函数指针。如果不修改对象,则应该使用函数调用操作符const
  2. 我会猜测函数运算符最终被内联并且您将断点放入函数对象的外联版本中。使用内联函数设置断点可能很棘手。您可能希望尝试将函数非内联用于测试目的。出于生产目的,您希望创建大多数谓词inline,因为存在巨大的性能差异。
  3. 当使用函数对象适配器(例如std::not1()与函数对象)时,它们需要定义某些嵌套类型。对于正常函数,可以容易地推导出相应的相关类型,例如返回类型和参数类型。对于函数对象,它们不能在C ++ 03中推导出来。在C ++ 11中,所有嵌套类型都不是必需的(如果我没记错的话)。在任何情况下,std::find_if()都不需要在调用它之前弄乱函数对象,即实际上不需要任何嵌套类型。
  4. 顺便说一下,你的谓词是否有任何理由不仅仅返回表达式的结果?也就是说,我会像这样实现它:

    struct checker {
        bool operator()(unsigned int i) const { return (i % 2) == 0; }
    };