C++之函数对象(Function Object) & for_each
来源:互联网 发布:福建 知乎 编辑:程序博客网 时间:2024/06/05 00:49
函数对象
对于一些用到函数作为参数的c++STL算法(如下面的for_each算法函数),函数的传递当然可以用泛化的函数指针来进行,但是c++STL常使用的是函数对象,目的在于更简洁、不依赖于当前计算机硬件体系的方式来表达算法。
一个函数对象,即一个重载了括号操作符“()”的对象。当用该对象调用此操作符时,其表现形式如同普通函数调用一般,因此取名叫函数对象。可以参考如下链接
http://blog.csdn.net/bonchoix/article/details/8050627#reply
在c++STL中,定义了若干函数对象,包括算数运算(plus,minus,multiplies,divides,modulus和negate),用于比较(equal_to,not_equal_to,less,greater,less_equal和greater_equal)以及逻辑运算(logical_and,logical_or,logical_not)等
for_each
如下,for_each函数的实现代码,内部使用了一个for循环,逐一遍历迭代器[first,last)【左闭右开】,然后调用f进行操作。可见,for_each函数并没有修改任何元素数据,只有执行的【对象】f会改动数据(所以不是严格意义的非变易函数)
template<class InputIter,class Function>Function for_each(InputIter first, InputIter last, Function f) {for (; first != last; ++first)f(*first); //调用f对象的函数operator(),对每个元素进行处理return f; //返回函数对象}
需要注意的是(1)f是对象!对象!对象!不是函数,对数据进行处理的是f的重载后的operator(),所以返回值是在对象f成员变量基础上运算得到的;
(2)这里函数采用值传递(而不是引用),所以该函数将对象f返回,用以将处理后的数据保存下来(实际是对象f发生了变化,将f返回即可读取处理后的数据),若函数无返回值,则形参f不会发生变化,后续有代码为例。
代码
先看下其他大佬http://blog.csdn.net/y1196645376/article/details/51289254写的
class Average{public:Average():count(0), sum(0){ }void operator()(double num) //每次调用这个仿函数就相当于往里面添加了一个数{count++; sum += num; cout<<3*num<<endl; //为了便于调试观察,特将各数值输出}double GetAverage(){ return sum / count; } //最后由这个方法得到当前的平均值private:int count;double sum;};template < class T ,class F>F For_each(T begin, T end, F functor){for (T it = begin; it != end; it++)functor(*it);return functor;}int main(){vector<int> arr = { 1, 2, 3, 4, 5 };Average result = For_each(arr.begin(), arr.end(), Average()); //这里的Average()相当于一个临时对象cout << result.GetAverage() << endl;return 0;}
期初这句话没看懂,一直以为Average()是调用重载()函数,【就是前面的注意(1)f是对象,不是函数】
Average result = For_each(arr.begin(), arr.end(), Average()); //这里的Average()相当于一个临时对象
导致一直理解为返回的functor一直没变
return functor;
后来才理解,这里Average()相当于构造函数,创建了一个默认参数对象,调用该对象的重载函数,依次对arr数据处理,最后返回改变后的对象(相当于借助arr各个数据,改变对象,最后返回)
为了验证上面说法,特将上述代码主函数部分修改如下
int main(){vector<int> arr = { 1, 2, 3, 4, 5 };Average result,r1;result = For_each(arr.begin(), arr.end(),r1); double ave = result.GetAverage();return 0;}
可以发现结果
r1作为形参传递,最后结果r1没变,而运算结果以对象形式返回给了result,发生了变化
再在类Average中添加构造函数
Average(int a, int b) { count = a; sum = b; }并将主函数改成
int main(){vector<int> arr = { 1, 2, 3, 4, 5 };Average result,r1(0,5);result = For_each(arr.begin(), arr.end(),r1); double ave = result.GetAverage();return 0;}发现结果
result结果是在r1基础上,以arr数据进行r1的重载函数【operator()】处理
综合上述结果,可以验证前述结论
本人新手,理解比较浅显,望大佬多多指正!
- C++之函数对象(Function Object) & for_each
- STL for_each 和函数对象(function object) 使用详解
- STL for_each 和函数对象(function object) 使用详解
- 函数对象状态(Function Object State)获取 -- 引用传递和for_each()
- 函数对象 function object
- 函数对象 function object
- C++中的函数对象(Function Object)
- C++中的函数对象(Function Object)
- 认识js函数对象(Function Object)
- C++函数对象 (Function object)
- C++之函数对象/伪函数(Function Object)详解(一)
- C++之函数对象/伪函数(Function Object)详解(二)
- for_each()使用函数对象
- C++中的函数对象(Function Object)(一)
- C++中的函数对象(Function Object)(二)
- C++函数对象(Function Object)(一)
- 函数对象(function object)的简单讲解
- C++11系列——函数对象(Function Object)
- 自己编写Android Studio插件 别停留在用的程度了
- jsp中使用EL表达式,出现Uncaught SyntaxError: Unexpected number错误
- pandas学习笔记5—DataFrame数据筛选loc,iloc,ix,at,iat
- PHP操作MongoDB
- python运算符
- C++之函数对象(Function Object) & for_each
- MPC-BE [Media Player Classic
- RSA密码
- Pod 私有化本地仓库
- 埃式筛法模板及其改进
- LeetCode 学习 LinkedList 专项(1)—— Delete Node in a Linked List
- Maven的存储库问题
- 鲁棒性
- java数据结构和算法