在前面几篇中,已经有过好几次的仿函数结合遍历、查找等算法的使用了,这边再进行归纳一下。
仿函数(函数对象)
前面已经说过了,仿函数的特点有:
- 是个类,不是个函数,可以说成是函数对象。
- 重载()。
- 内部可以声明一些变量,保存状态,如声明一个整型变量记录调用次数。
- 仿函数通常不声明构造函数和析构函数,因此构造和析构时不会发生问题,避免了函数调用时的运行问题。
- 可内联编译。 使用函数指针就不大可能了,因为不知道函数指针的具体内容到底适不适合内联。
- 模板函数使得通用性更强。
一元、二元仿函数
所以一元二元,就是指重载函数operator()的参数有几个,一个称为一元,两个称为二元。
仿函数作为一种 策略 使用,配合算法能够让我们获得想要的结果。
可能 策略 这个词初看不能理解,下面就看看例子吧。
在看例子之前先看看for_each的原型:
// 返回类型为仿函数类型,接受两个指针和一个仿函数 Function for_each (InputIterator first, InputIterator last, Function fn);现在我要使用for_each算法,遍历vector容器,且还要输出它。
//仿函数 class MyPrint { public: MyPrint() {m_Num = 0;} int m_Num; public: //重载,策略为输出,然后次数+1 void operator() (int num) { cout << num << " "; m_Num++; } }; int main() { vector<int> v; for (int i = 0; i < 10; ++i) { v.push_back(i); } //调用 MyPrint my = for_each(v.begin(), v.end(), MyPrint()); cout << endl << my.m_Num << endl; return 0; }看看输出结果:
可以看到我们已经正确输出了容器中的元素,且内部保存的状态也得以正确保存。看我们的仿函数,策略就是输出元素。
谓词
谓词是指普通函数或重载的operator()返回值是bool类型的函数对象(仿函数)。如果operator接受一个参数,那么叫做一元谓词,如果接受两个参数,那么叫做二元谓词,谓词可作为一个判断式。这个判断式,也可看做策略。
谓词和仿函数有几分相似,只是返回值确定为bool型的。用法也几乎一样。
谓词可分一元谓词和二元谓词。 根据各自策略不同,比如二元谓词可以用来做降序排列,这在前几篇都有讲过。只要规定一个排序规则即可。如:
class MyCmp { public: bool operator()(int a,int b) return a > b; };那一元排序也有自己的用途,比如我想在容器中找到大于5的数字:
class MyCmp { public: bool operator()(int v) return v > 5; }; int main() { vector<int> v; for (int i = 0; i < 10;i ++) { v.push_back(i); } vector<int>::iterator it = find_if(v.begin(), v.end(), GreaterThenFive()); if (it == v.end()) cout << "没有找到" << endl; else
