C++11中所谓的函数对象和谓词

1、函数对象

答:在《C++ Primer Plus》里面,函数对象是可以以函数方式与()结合使用的任意对象。这包括函数名、指向函数的指针和重载了“operator()”操作符的类对象。(C++11后更多的是使用重载“operator()”这种方式来使用函数对象),例如:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

class FuncObject{
public: 
    FuncObject(int n = 0) : num(n), count(1){}

    bool operator()(int) {
        return count++ == num;
    }

    int GetCount(){
        return count;
    }
private:
    int count;
    int num;
};

int main(){
    int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    vector<int> vec(a, a + 10);
    FuncObject test(3);  
    vector<int>::iterator itr = find_if(vec.begin(),vec.end(), test);  
    cout << "3rd:" << *itr << endl;  
    cout << "State:" << test.GetCount() << endl; 

}
 

2、谓词

答:在《C++ Primer》里面,谓词是一个可调用的表达式,其返回结果是一个能作为判断条件的值。(也有通俗的叫法是返回bool类型的仿函数称为谓词)

标准库使用的算法包括两种谓词:一元谓词(只接受一个参数)和二元谓词(只接受两个参数)。

例如下面是一个二元谓词: 

bool   isShort(const string &s1, const string &s2)

 {

           return s1<s2;

 }

先来看看sort的原型:

template <class RandomAccessIterator>  

void sort ( RandomAccessIterator first, RandomAccessIterator last );  

template <class RandomAccessIterator, class Compare>  

void sort ( RandomAccessIterator first, RandomAccessIterator last, Compare comp );

可见第二个版本是可以指定第三个参数,这里我们使用一个二元谓词:

vector<string>  vecStr={"12432", "sadf", "hjjhh"};

sort(vecStr.begin(), vecStr.end(), isShort);

当然我们的谓词也可以这样写:

class isShorter

{

public:

          bool operator()(const string &s1, const string &s2)

         {

  1.           return s1<s2;

         }

};

调用就是这样:

sort(vecStr.begin(), vecStr.end(), isShorter());

注意:使用函数对象(重载了operator()的类对象,这里和叫它谓词还是函数对象就没有区别了)时要跟一个"()"来调用该操作符,而函数指针不用“()”,也就是说应该是存在从函数指针到函数对象的一个转换。

总结:我们使用的find_if第三个参数接收是一个函数对象,sort的第三个参数是接收二元谓词的一个版本,可发现一些共同点:

(1)谓词属于函数对象的一种,它是函数对象的一个分支,它们存在转换关系。

(2)不管是函数指针还是类对象,"()"得到的参数都是直接从算法遍历中获取来的,故形参类型需要和遍历的元素类型是一致的。如果有其它更严格的比较规则,可以使用重载operator()的类对象,比如需要判断遍历的元素是否大于某个传入的值,则可以用类对象的构造函数来保存到成员中,然后后面在重载的operator()函数中使用该值即可。

C++很多标准库算法都使用的是谓词,当然谓词有一些局限性(比如只接受一元和二元参数),很多时候我们会用重载operator()的类对象来操作。

猜你喜欢

转载自blog.csdn.net/qq_38915078/article/details/106648953
今日推荐