函数对象

重载函数调用操作符的类,其对象常称为函数对象,即他们是行为类似函数的对象,也叫仿函数,其实就是重载”()”操作符,使得类对象可以像函数一样调用。

Note

  1. 函数对象是一个类,不是一个函数
  2. 函数对象(仿函数)重载了”()” 操作符使得它可以像函数一样调用
    分类:假定某个类有一个重载的operator(),而且重载的operator()要求获取一个参数,我们就将这个类称为”一元仿函数”(unary functior),相反,如果重载的operator()要求获取两个参数,就将这个类称为”二元仿函数”(binary functor)

作用

STL提供的算法往往都有两个版本,其中一个版本表现出最常用的某种运算,另一个版本则是允许用户通过template参数的形式来指定所要采取的策略。

代码例子

/*************************************************************************
	> File Name: main.cpp
	> Author: 仿函数的使用方法
	> Mail: 
	> Created Time: 2019年12月31日 星期二 16时09分25秒
 ************************************************************************/

# include<iostream>
using namespace std;
class MyPrint
{
    public:
    void operator()(int num)
    {
        cout<<"Here "<<count++<<" is MyPrint:"<<num<<endl;

    }
    private:
        int count=0; //保存内部状态
};
//函数对象作为参数
void test01()
{
    cout<<"test01"<<endl;
    MyPrint myPrint;
    myPrint(10);
    myPrint(10);
    myPrint(10);
    myPrint(10);

}
void doPrint(MyPrint print,int num)
{
    cout<<"doPrint:";
    print(num);
}
int main()
{
    test01();
    MyPrint()(1234); //匿名对象的调用方式 
    doPrint(MyPrint(),1001); //传递匿名对象
    return 0;
}

仿函数.bmp

总结

  1. 函数对象通常不定义构造函数和析构函数,所以在构造和析构时不会发生任何问题,避免了函数调用的运行时问题。
  2. 函数对象超出了普通函数的概念,函数对象可以有自己的状态
  3. 函数对象可内联编译,性能好,用函数指针几乎不可能
  4. 模板函数对象使函数对象具有通用性,这也是它的优势之一。

谓词

谓词就是返回值为bool的普通函数或者是仿函数,根据参数的个数也有一元谓词和二元谓词.

示例代码

/*************************************************************************
	> File Name: main.cpp
	> Author: 
	> Mail: 
	> Created Time: 2019年12月31日 星期二 16时29分35秒
 ************************************************************************/

# include<iostream>
# include <vector>
# include <algorithm>
using namespace std;
//一元谓词
class GreaterThen20{
    public :bool operator()(const int & val)
    {
        return val>20;
    }
};
void test01()
{
    vector<int> v;
    v.push_back(10);
    v.push_back(20);
    v.push_back(30);
    v.push_back(40);
    //查找第一个大于20的数字

    if(find_if(v.begin(),v.end(),GreaterThen20())!=v.end());
        cout<<"找到了"<<endl;
}
//二元谓词
class MyCompare{
    public :
        bool operator()(const int &v1,const int &v2)
        { return v1>v2; }
};
void test02()
{
    vector<int> v;
    v.push_back(10);
    v.push_back(20);
    v.push_back(30);
    v.push_back(40);
    sort(v.begin(),v.end(),MyCompare());
    //匿名函数 lambda表达式   [](){}
    for_each(v.begin(),v.end(),[](int val){cout<<val<<" ";});
}
int main()
{
    test01();
    test02();
    return 0;
}

谓词.bmp

内建函数对象

STL内建了一些函数对象,分为算术类函数对象,关系运算类函数对象,逻辑运算类仿函数。这些仿函数所产生的对象,用发货一般函数完全相同,当然我们还可以产生无名的临时对象来履行函数功能。使用内建函数对象需要引入头文件# include

6个算术类函数对象,除了negate是一元运算,其他都是二元运算

template<class T> T plus<T> //加法仿函数
template<class T> T minius<t> //加法仿函数
template<class T> T multiplies<T> //乘法仿函数
template<class T> T divides<T> //除法仿函数
template<class T> T modulus<T> //取模仿函数
template<class T> T negate<T> //取反仿函数

6个关系运算类函数对象,每一种都是二元谓词

template<class T> bool equal_to<T>  //等于
template<class T> bool not_equal_to<T> //不等于
template<class T> bool greater<T> //大于
template<class T> bool greater_equal<T> //大于等于
template<class T> bool less<T> //小于
template<class T> bool less_equal<T> //小于等于

逻辑运算类运算函数,not为一元谓词,其余都是二元谓词

template<class T> bool logical_and<T> //逻辑与
template<class T> bool logical_ro<T> //逻辑或
template<class T> bool logical_not<T> //逻辑非

代码示例

/*************************************************************************
	> File Name: main.cpp
	> Author: 内建函数对象
	> Mail: 
	> Created Time: 2019年12月31日 星期二 16时46分37秒
 ************************************************************************/

# include <vector>
# include<iostream>
# include <functional>
# include <algorithm>
using namespace std;

void test01()
{
    
    negate<int> n; //取反
    cout<<"negate:"<<n(10)<<endl;
    
    plus<int> p;
    cout<<"plus: "<<p(1,1)<<endl;


}
void test02()
{
    vector<int> v;
    v.push_back(10);
    v.push_back(20);
    v.push_back(30);
    sort(v.begin(),v.end(),greater<int>());
    for_each(v.begin(),v.end(),[](int val){cout<<val<<" ";});
    
}
int main()
{
    test01();
    test02();
    return 0;
}

内建函数对象.bmp