定义:
返回值是bool的仿函数叫谓词,operator()该仿函数有一个参数叫一元谓词,有两个参数叫二元谓词
一,谓词
1,一元谓词:
例如find_if()函数,先看看源码:
前两个参数分别是起始、结束迭代器,第三个参数就是一个对象,其作用就是提供个规则,让程序按照这个规则来找到第一个符合条件的迭代器,我们传入时要传入一个对象:
class MyCompare{
public:
bool MyCompare()(int value){
if(value > 5){
return true; //这里我们指定的规则是大于5即是true
}
}
}
void test(){
vector<int> v;
...
vector<int>::iterator it = find_if(v.begin(), v.end(), MyCompare());
if(it!=v.end()){ //第三个参数MyCompare()是一个临时对象
//找到了第一个大于5的元素
}
}
2,二元谓词:
例如sort()函数:
class MyCompare{
public:
bool MyCompare()(int value1, int value2){
return value1 > value2; //指定排序规则是降序
}
}
void test(){
vector<int> v;
...
//第三个参数,MyCompare()是一个临时对象,用于指定排序规则
sort(v.begin(), v.end(), MyCompare());
}
二,内建函数对象
STL内置的一些仿函数,使用时要#include < functional >
1,算术仿函数
其中negate是一元运算,其他的是二元运算。
template<class T> T plus<T> //加
template<class T> T minus<T> //减
template<class T> T multiplies<T> //乘
template<class T> T divides<T> //除
template<class T> T negate<T> //取反
使用举例:
#include <functional>
void test(){
negate<int> n; //这句话的意思是使用内建函数对象negate,创建了一个对象n
//既然n是一个对象,那么n(50)就代表调用了n的仿函数,传入参数是50,结果是-50
cout<<n(50)<< endl;
//同样的,plus是二元谓词,下面结果是30
plus<int> p;
p(10, 20);
}
2,关系仿函数
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> //小于等于
使用举例:让sort()函数降序排列
#include <functional>
class MyCompare{
public:
bool MyCompare(int value1, value2){
return value1 > value2;
}
}
void test(){
vector<int> v;
...
//方式一,我们自己写的一个仿函数,传入一个临时对象
sort(v.begin(), v.end(), MyCompare());
//方式二,使用内建函数对象,传入一个greater<int>类型的临时对象
sort(v.begin(), v.end(), greater<int>())
}
看下sort( )函数源码:
怪不得默认是升序,原来在不传入第三个参数用于指定规则时,默认使用了less<>( )
3,逻辑仿函数
template<class T> bool logical_and<T> //逻辑与
template<class T> bool logical_or<T> //逻辑或
template<class T> bool logical_not<T> //逻辑非
例如:transform()函数
#include <functional>
#incldue <algorithm>
void test(){
vector<bool> v;
...
vector<bool> v2;
v2.resize(v.size());
/*
搬运函数,参数分别是源数据元素的起始、终点迭代器,要搬到哪去(目标起始位置),仿函数,用于在搬运途中做些操作,比如我们用
*/
/*
logical<bool>(),意思就是在搬运途中将这些值全部取非,如果搬运前是true,true,false; 目标容器里就是false, false, true
*/
transform(v.begin(), v.end(), v2.begin(), logical_not<bool>());
}