1.函数对象

重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象。一个类对象,表现出一个函数的特征,就是通过“对象名+(参数列表)”的方式使用一个类对象,如果没有上下文,完全可以把它看作一个函数对待。
这是通过重载类的operator()来实现的。
“在标准库中,函数对象被广泛地使用以获得弹性”,标准库中的很多算法都可以使用函数对象或者函数来作为自定的回调行为;

一元函数对象:函数参数1个;
二元函数对象:函数参数2个;

2.谓词

一元谓词: 函数参数1个,函数返回值是bool类型,可以作为一个判断式

二元谓词: 函数参数2个,函数返回值是bool类型

谓词可以使一个仿函数,也可以是一个回调函数。

一元谓词举例如下:
1.判断给出的string对象的长度是否小于6

bool GT6(const string &s)
{
return s.size() >= 6;
}

2.判断给出的int是否在3到8之间

bool Compare( int i )
{
return ( i >= 3 && i <= 8 );
}

二元谓词举例如下:
1.比较两个string对象,返回一个bool值,指出第一个string是否比第二个短

bool isShorter(const string &s1, const string &s2)
{
return s1.size() < s2.size();
}

3.一元函数对象案例

//1普通类 重载 函数调用操作符
template <typename T>
void FuncShowElemt(T &t)  //普通函数 不能像 仿函数那样记录状态
{cout << t << " ";
};void showChar(char &t)
{cout << t << " ";
}//函数模板 重载 函数调用操作符
template <typename T>
class ShowElemt
{
public:ShowElemt(){n = 0;}void operator()(T &t){n++;cout << t << " ";}void printCount(){cout << n << endl;}
public:int n;
};//1 函数对象 基本使用
void main11()
{int a = 100;FuncShowElemt<int>(a); //普通的函数调用ShowElemt<int> showElemt; //函数对象 showElemt(a); //函数对象调用
}

4.一元谓词案例

//1元谓词 例子
template <typename T>
class Isdiv
{
public:Isdiv(const T &divisor) //{this->divisor = divisor;}bool operator()(T &t){return (t%divisor == 0);}
protected:
private:T divisor;
};void main13()
{vector<int> v2;for (int i=10; i<33; i++){v2.push_back(i);}vector<int>::iterator it;int a = 4;Isdiv<int> mydiv(a);// _InIt find_if(_InIt _First, _InIt _Last, _Pr _Pred)   //返回的是迭代器it = find_if(v2.begin(), v2.end(), Isdiv<int>(4));if (it != v2.end()){cout << "第一个被4整除的数是:" << *it << endl;}
}

5.二元函数对象案例

template <typename T>
struct SumAdd
{T operator()(T &t1, T &t2){return t1 + t2;}
};template <typename T>
void printE(T &t)
{for (vector<int>::iterator it = t.begin(); it!=t.end(); it++ ){cout << *it << " ";}
}void printVector(vector<int> &v)
{for (vector<int>::iterator it = v.begin(); it!=v.end(); it++ ){cout << *it << " ";}
}void  main14()
{vector<int> v1, v2 ;vector<int> v3;v1.push_back(1);v1.push_back(2);v1.push_back(3);v2.push_back(4);v2.push_back(5);v2.push_back(6);v3.resize(10);//transform(v1.begin(), v1.end(), v2.begin(),v3.begin(), SumAdd<int>());/*template<class _InIt1,class _InIt2,class _OutIt,class _Fn2> inline_OutIt transform(_InIt1 _First1, _InIt1 _Last1,_InIt2 _First2, _OutIt _Dest, _Fn2 _Func)*/vector<int>::iterator it = transform(v1.begin(), v1.end(), v2.begin(),v3.begin(), SumAdd<int>());cout << *it << endl;printE(v3);
}

6.二元谓词案例

void current(int &v)
{cout << v << " ";
}bool MyCompare(const int &a, const int &b)
{return a < b;
}
void main15()
{vector<int> v(10);for (int i=0; i<10; i++){v[i] = rand() % 100;}for_each(v.begin(), v.end(), current);printf("\n");sort(v.begin(), v.end(), MyCompare );printf("\n");for (int i=0; i<10; i++){printf("%d ", v[i]);}printf("\n");
}

7.综合示例代码

#include <iostream>
using namespace std;#include "string"
#include <vector>
#include <list>
#include "set"
#include <algorithm>
#include "functional"//函数对象 类重载了()
template <typename T>
class ShowElemt
{
public:ShowElemt(){n = 0;}void operator()(T &t){n ++;//printN();cout << t << " ";}void printN(){cout << "n:" << n << endl;}
protected:
private:int n;
};//函数模板  ==函数
template <typename T>
void FuncShowElemt(T &t)
{cout << t << endl;
}//普通函数
void FuncShowElemt2(int &t)
{cout << t << " ";
}//函数对象 定义 ;  函数对象和普通函数的异同
//
void main01()
{int a = 10;ShowElemt<int> showElemt;showElemt(a); //函数对象的()的执行 很像一个函数 //仿函数FuncShowElemt<int>(a);FuncShowElemt2(a);
}//函数对象是属于类对象,能突破函数的概念,能保持调用状态信息
//函数对象的好处
// for_each算法中, 函数对象做函数参数
// for_each算法中, 函数对象当返回值
void main02()
{vector<int> v1;v1.push_back(1);v1.push_back(3);v1.push_back(5);for_each(v1.begin(), v1.end(), ShowElemt<int>()); //匿名函数对象 匿名仿函数cout << endl;for_each(v1.begin(), v1.end(), FuncShowElemt2); //通过回调函数  谁使用for_each 谁去填写回调函数的入口地址ShowElemt<int> show1;//函数对象 做函数参数 /*template<class _InIt,class _Fn1> inline_Fn1 for_each(_InIt _First, _InIt _Last, _Fn1 _Func){   // perform function for each element_DEBUG_RANGE(_First, _Last);_DEBUG_POINTER(_Func);return (_For_each(_Unchecked(_First), _Unchecked(_Last), _Func));}*///1 for_each算法的 函数对象的传递 是元素值传递 ,不是引用传递for_each(v1.begin(), v1.end(), show1);show1.printN();cout << "通过for_each算法的返回值看调用的次数" << endl;show1 = for_each(v1.begin(), v1.end(), show1);show1.printN();//结论 要点: 分清楚 stl算法返回的值是迭代器 还是 谓词(函数对象) 是stl算法入门的重要点
}template<typename T>
class IsDiv
{
public:IsDiv(const T &divisor){this->divisor = divisor;}bool operator()(T  &t){return (t%divisor == 0);}protected:
private:T divisor;
};void main03()
{vector<int> v2;for (int i=10; i<33; i++){v2.push_back(i);}int a = 4;IsDiv<int> myDiv(a);//find_if(v2.begin(), v2.end(), myDiv );/*template<class _InIt,class _Pr> inline_InIt find_if(_InIt _First, _InIt _Last, _Pr _Pred){   // find first satisfying _Pred_DEBUG_RANGE(_First, _Last);_DEBUG_POINTER(_Pred);return (_Rechecked(_First,_Find_if(_Unchecked(_First), _Unchecked(_Last), _Pred)));}//find_if返回值是一个迭代器 //要点: 分清楚 stl算法返回的值是迭代器 还是 谓词(函数对象) 是stl算法入门的重要点*/vector<int>::iterator it;it = find_if(v2.begin(), v2.end(), IsDiv<int>(a) );if (it == v2.end()){cout << "容器中没有被4整除的元素" << endl;}else{cout <<"第一个是被4整除的元素是:" << *it << endl;}}//二元函数对象
template <typename T>
class SumAdd
{
public:T operator()(T t1, T t2){return t1 + t2;}
};void main04()
{//v1 v2 ==> v3vector<int> v1, v2;vector<int> v3;v1.push_back(1);v1.push_back(3);v1.push_back(5);v2.push_back(2);v2.push_back(4);v2.push_back(6);v3.resize(10);/*template<class _InIt1,class _InIt2,class _OutIt,class _Fn2> inline_OutIt transform(_InIt1 _First1, _InIt1 _Last1,_InIt2 _First2, _OutIt _Dest, _Fn2 _Func){   // transform [_First1, _Last1) and [_First2, ...) with _Func_DEBUG_RANGE(_First1, _Last1);_DEBUG_POINTER(_Dest);_DEBUG_POINTER(_Func);if (_First1 != _Last1)return (_Transform2(_Unchecked(_First1), _Unchecked(_Last1),_First2, _Dest, _Func,_Is_checked(_Dest)));return (_Dest);}//transform 把运算结果的 迭代器的开始位置 返回出来 */transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), SumAdd<int>() );for (vector<int>::iterator it=v3.begin(); it!=v3.end(); it++ ){cout << *it << " ";}cout << endl;
}bool MyCompare(const int &a, const int &b)
{return a < b; //从小到大
}void main05()
{vector<int> v1(10);for (int i=0; i<10; i++){int tmp = rand() %100;v1[i] = tmp;}for (vector<int>::iterator it=v1.begin(); it!=v1.end(); it++ ){cout << *it <<" ";}cout << endl;for_each(v1.begin(), v1.end(), FuncShowElemt2);cout << endl;sort(v1.begin(), v1.end(), MyCompare);for_each(v1.begin(), v1.end(), FuncShowElemt2);cout << endl;
}struct CompareNoCase
{bool operator()(const string &str1, const string &str2){string str1_ ;str1_.resize(str1.size() );transform(str1.begin(), str1.end(), str1_.begin(), tolower ); //预定义函数对象 string str2_ ;str2_.resize(str2.size() );transform(str2.begin(), str2.end(), str2_.begin(), tolower ); //预定义函数对象 return (str1_ < str2_); // 从小到大进行排序}
};
void  main06()
{set<string> set1;set1.insert("bbb");set1.insert("aaa");set1.insert("ccc");set<string>::iterator it = set1.find("aAa"); //find函数 默认 区分大小写if (it == set1.end()){cout << " 没有 查找到 aaa " << endl;}else{cout << " 查找到 aaa " << endl;}set<string, CompareNoCase> set2;set2.insert("bbb");set2.insert("aaa");set2.insert("ccc");set<string, CompareNoCase>::iterator it2 = set2.find("aAa");if (it2 == set2.end()){cout << " 没有 查找到 aaa " << endl;}else{cout << " 不区分大小的的查找  查找到 aaa " << endl;}}void main1111()
{//main01(); //函数对象基本概念//main02(); //函数对象的好处 函数对象做函数参数 函数对象做返回值//main03(); //一元谓词//main04(); //二元函数对象 和二元谓词//main05(); //二元函数对象 和二元谓词main06(); //二元谓词在set集合中的应用cout<<"hello..."<<endl;system("pause");return ;
}

8.预定义函数对象

标准模板库STL提前定义了很多预定义函数对象,#include <functional> 必须包含。

//1使用预定义函数对象:
//类模板plus<> 实现了: 不同类型的数据进行加法运算
void main41()
{plus<int> intAdd;int x = 10;int y = 20;int z = intAdd(x, y); //等价于 x + y cout << z << endl;plus<string> stringAdd;string myc = stringAdd("aaa", "bbb");cout << myc << endl;vector<string> v1;v1.push_back("bbb");v1.push_back("aaa");v1.push_back("ccc");v1.push_back("zzzz");//缺省情况下,sort()用底层元素类型的小于操作符以升序排列容器的元素。//为了降序,可以传递预定义的类模板greater,它调用底层元素类型的大于操作符:cout << "sort()函数排序" << endl;;sort(v1.begin(), v1.end(), greater<string>() ); //从大到小for (vector<string>::iterator it=v1.begin(); it!=v1.end(); it++ ){cout << *it << endl;}
}

8.1算术函数对象

预定义的函数对象支持加、减、乘、除、求余和取反。调用的操作符是与type相关联的实例

//加法:plus<Types>
plus<string> stringAdd;
sres = stringAdd(sva1,sva2);减法:minus<Types>
乘法:multiplies<Types>
除法divides<Tpye>
求余:modulus<Tpye>
取反:negate<Type>
negate<int> intNegate;
ires = intNegate(ires);
Ires= UnaryFunc(negate<int>(),Ival1);

8.2关系函数对象

等于equal_to<Tpye>
equal_to<string> stringEqual;
sres = stringEqual(sval1,sval2);
不等于not_equal_to<Type>
大于 greater<Type>
大于等于greater_equal<Type>
小于 less<Type>
小于等于less_equal<Type>
void main42()
{vector<string> v1;v1.push_back("bbb");v1.push_back("aaa");v1.push_back("ccc");v1.push_back("zzzz");v1.push_back("ccc");string s1 = "ccc";//int num = count_if(v1.begin(),v1.end(), equal_to<string>(),s1);int num = count_if(v1.begin(),v1.end(),bind2nd(equal_to<string>(), s1));cout << num << endl;
} 

8.3逻辑函数对象

逻辑与 logical_and<Type>
logical_and<int> indAnd;
ires = intAnd(ival1,ival2);
dres=BinaryFunc( logical_and<double>(),dval1,dval2);
逻辑或logical_or<Type>
逻辑非logical_not<Type>
logical_not<int> IntNot;
Ires = IntNot(ival1);
Dres=UnaryFunc( logical_not<double>,dval1);

STL之函数对象和谓词相关推荐

  1. STL算法中函数对象和谓词

    算法中函数对象和谓词 函数对象和谓词定义 函数对象 谓词 一元函数对象案例 一元谓词案例 二元函数对象案例 二元谓词案例 预定义函数对象和函数适配器 使用预定义函数对象 算术函数对象 关系函数对象 逻 ...

  2. C++模板学习之函数对象之谓词

    函数对象是用对象来表示的函数: 可以执行operator()的对象都叫做函数对象. 谓词是那些返回bool,operator()操作的函数对象. 考虑如何对一个序列求和: 函数对象的优势在于可以将参数 ...

  3. c++中STL的常用算法--1(函数对象,谓词,内建函数对象)

    函数对象 重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象,也叫仿函数(functor),其实就是重载"()"操作符,使得 ...

  4. STL算法——函数对象(仿函数)

    全部案例链接 https://download.csdn.net/download/weixin_45525272/12536637 1 函数对象 重载函数调用操作符的类,其对象常称为函数对象(fun ...

  5. STL运用的C++技术(6)——函数对象

    http://blog.csdn.net/wuzhekai1985/article/details/6658940?_t_t_t=0.20427969420870595 STL是C++标准库的重要组成 ...

  6. C++STL总结笔记(二)——仿函数(函数对象)

    文章目录 一.概念 总结 一.概念 仿函数又称函数对象,即重载了函数调用运算符()的类的对象. 优势: 1.仿函数对象的内部可以有自己的状态,可以实现一些其他的功能. 2.函数对象可以作为参数进行传递 ...

  7. 【C++】【第六篇-2】【黑马 p215~p242】【list容器】【set/multiset容器】【map/multimap容器】【函数对象】【谓词】【内建函数对象】

    [C++][第六篇-2][黑马 p215~p242][list容器][set/multiset容器][map/multimap容器][函数对象][谓词][内建函数对象] 3.7 list容器(p215 ...

  8. C++提高编程(四)—— STL函数对象

    C++系列内容的学习目录→\rightarrow→C++学习系列内容汇总. 1. 函数对象 1.1 函数对象概念 1.2 函数对象使用 2. 谓词 2.1 谓词概念 2.2 一元谓词 2.3 二元谓词 ...

  9. 18函数对象19command模式20函数对象在STL中的应用

    Item 18. Function Objects Item 19. Commands and Hollywood Item 20. STL Function Objects 1.unction Ob ...

最新文章

  1. 十一、Python异常处理
  2. 计算机领域的范式,编程领域的范式转移
  3. Spring Statemachine TODO
  4. linux 连接wifi不稳定,rtl8188ce 无线网不稳定终极解决方案 - 哆啦比猫的技术瞎扯 - Arch Linux · ドラえもん · 实时绘制...
  5. mysql update 联合更新_Mysql update多表联合更新的方法小结
  6. Kerberos Hbase Api 操作
  7. 根据企业财务进行风险分析——基于pytorch
  8. opencv 矫正图片
  9. .net中序列化读写xml方法的总结
  10. centos 6 与 centos 7 服务开机启动、关闭设置的方法
  11. 基于二阶矩阵的最优化问题(二)(附matlab代码)
  12. 车载系统模块资料整理
  13. 学习Python的Django执行python manage.py startapp myApp创建应用出现的问题
  14. 在配置SSH免密登录时报错:/usr/bin/ssh-copy-id: ERROR: failed to open ID file '/root/.pub': 没有那个文件或目录
  15. 教你如何微信公众号图文中怎么下载封面图
  16. vivado中ZYNQ详解(主要用于PS和PL之间的工作衔接)
  17. IT职场: 选择外企利与弊
  18. mysql using temporary_执行计划中Using filesort,Using temporary相关语句的优化解决_MySQL
  19. [持续更新中]博客园开放api、还有知乎、V2EX开放接口
  20. 调用matlab dll报错,c#调用MATLAB的dll时出错

热门文章

  1. dart与java互调_Dart与Java不同的地方
  2. java 股票 代码_Java中利用散列表实现股票行情的查询_java
  3. html全屏播放一段视频,显示HTML5视频全屏(Show HTML5 Video Fullscreen)
  4. 编写程序,随机产生20个0到1之间的数,将这20个数写入文本文件中,要求每行5个数
  5. 基于多线程的TCP局域网通信,客户端向服务端上传 文件简单实现源码
  6. 一球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在 * 第10次落地时,共经过多少米?第10次反弹多高?
  7. dataset的去重计数 g2_向工程渣土运输车辆计数 漏洞损失说“不”
  8. Hibernate使用原生SQL适应复杂数据查询
  9. 剑指offer:22-25记录
  10. 《Python Cookbook 3rd》笔记(2.12):审查清理文本字符串