函数对象:定义了调用操作符()的类对象。当用该对象调用此操作符时,其表现形式如同普>通>函数调用一般,因此取名叫函数对象。
operator()
- 函数对象的实现主要通过在类中或者结构体中重载()操作符
operator()
class IsNeg {
public:
bool operator()(int val) {
return val > 0 ? false: true;
}
};
- 与普通函数相比,函数对象比函数更加灵活,类isNeg 中定义了操作符 ( ),isNeg 对象调用语句在形式上跟以下函数的调用完全一样:
int a = -1;
IsNeg isNeg
cout << isNeg(a);
函数对象的优势
- 函数对象可以有自己的状态(私有变量),我们可以在类中定义状态变量
- 函数对象有自己特有的类型。我们可以传递相应的类型作为参数来实例化相应的模板,比如说带参数的函数形参
使用函数对象的典型例子
定义排序规则
- 在容器
set
中对string 进行排序,首先来定义相应的类并定义operator()
来规定排序规则:
class cmp{
public:
bool operator() (const string &str1, const string &str2) const { //带两个参数
return str1 > str2;
}
};
set<string, cmp> myset; //带比较函数的set构造函数,并用函数对象cmp初始化
myset.insert("A");
myset.insert("B"); // 这样容器内容输出为BA
- 大根堆(有限队列)
struct node;
struct cmp {
bool operator()(node a,node b) {
if(a.x == b.x) return a.y >= b.y;
else return a.x > b.x;
}
};
priority_queue<node, vector<node>, cmp> que; // 大根堆 堆顶是最大值
谓词函数
-
谓词函数
通常用来对传进来的参数进行判断,并返回布尔值。但是一般的函数形式固化,比如字符串长度比较只能判断是否大于一个确定的长度值。 - 函数对象可以作为谓词函数,并可以在
类初始化时
传递参数,如字符串长度参考值,因此函数对象比普通函数更加灵活。
现在假设我们有一串数字,要从中找出第一个不小于10的数字。可以定义如下相应的类:
class Upper {
public:
Upper(int min = 0):min(min){}
bool operator() (int value) const {
return value >= min;
}
private:
int min;
};
从而这样调用 find_if 函数:
find_if(dest.begin(), dest.end(), Upper(10));
首先生成类 Upper 的对象,并用 10 初始化,调用find_if 时将用该函数对象进行判断。