https://blog.csdn.net/infoworld/article/details/38901127
在C++里,我们通过在一个类中重载括号运算符的方法使用一个函数对象而不是一个普通函数。
1、表达式格式
HWND operator ()() const throw() { return m_hWnd; }
与类型改变表达式格式区别:
operator HWND() const throw() { return m_hWnd; }
案例:
#include <iostream> #include <string> #include <vector> #include <algorithm> #include <iterator> using namespace std; template <typename T> class search_num { T m_val; public: search_num(T value):m_val(value) { cout << " construct " <<value<< endl; } bool operator()(const T val){ cout << "opeatorr()" << endl; return (m_val == val); } }; int main() { vector<int> v; for (int i = 1; i < 6; i++) { v.push_back(i); } vector<int>::iterator it = find_if(v.begin(), v.end(), search_num<int>(4)); if (it != v.end()) { cout << " find num " << *it << endl; } else { cout << "not find the num" << endl; } return 0; }
vector<int>::iterator it = find_if(v.begin(), v.end(), search_num<int>(4));
注意这里的search_num<int>(4)只是实例化,没有传入参数;完整调用是:实例化+参数表;
find_if函数只需要判断函数传入指针;https://blog.csdn.net/u010949971/article/details/61192368
#include <iostream> #include <string> #include <string.h> #include <stdlib.h> #include <stdio.h> using namespace std; class Total { public: Total(float sum,float discount) { sum_ = sum; discount_ = discount; } ~Total(){} operator float() { return sum_* discount_; } operator std::string() { char str[128]; sprintf(str,"%f",sum_* discount_); return std::string(str); } float operator()() { return sum_* discount_; } float sum_; float discount_; }; int main(int argc, char const *argv[]) { Total to(89,0.8); cout << to << endl; cout << to() << endl; cout << (std::string)to << endl; //cout << to(0.9) << endl; return 0; }
2、调用方式:两种
先声明;再实例化;再调用,用对象调用operator();
#include <iostream> using namespace std; template<typename T> struct m_plus { T operator()(const T& x, const T& y) { return x + y; } }; int main(int argc, char *argv[]) { // 定义其对象 调用其operator() m_plus<int> op; cout << op(1, 2) << endl; // 产生一个匿名对象 这是仿函数的主流用法 cout << m_plus<int>()(1, 2) << endl; return 0; }
仿函数跟函数对比:为什么不直接使用函数指针代替呢?
1.仿函数可以有自己的状态,而函数指针则不行(有的使用template或者static变量可以实现)。
我们可以这样子使用仿函数:
#include <iostream> using namespace std; template<typename T, T add> struct m_plus { m_plus() { _add = add; } T operator()(const T& x) { return x + _add; } // 仿函数可以具有自己的状态 int _add; }; int main(int argc, char *argv[]) { m_plus<int, 10> op; cout << op(100) << endl; cout << op(200) << endl; return 0; }
2.仿函数可以与函数适配器搭配使用。
举一个例子,例如我们如果要使用count_if算法来计算容器中大于10的元素的个数。
如果我们使用greater<int>作为判别式(二元),而count_if只接受一个一元判别式,这时候我们就需要搭配函数适配器一起使用了。
而函数指针不能直接搭配函数适配器一起使用;
#include <iostream> #include <vector> #include <functional> #include <algorithm> using namespace std; int main(int argc, char *argv[]) { vector<int> coll{ 1, 3, 5, 7, 9, 11, 13, 15 }; // 接着下面有bind2nd的具体实现 cout << count_if(coll.begin(), coll.end(), bind2nd(greater<int>(), 10)) << endl; return 0; }
3.与公共的函数相比,公共函数用到的一些变量,就可能成为公共的全局变量;而且不是很好维护,对于仿函数,写一个简单类,除了那些维护一个类的成员函数外,就只是实现一个operator(),在类实例化时,就将要用的,非参数的元素传入类中,这样就免去了对一些公共变量的全局化的维护了;
4.仿函数,还可以用关联,聚合,依赖的类之间的关系,与用到他们的类组合在一起,这样有利于资源的管理(这点可能是它相对于函数最显著的优点了);
5.仿函数,如果在配合上模板技术和policy编程思想,那就更是威力无穷了,大家可以慢慢的体会;