谓词函数:什么谓词,其实就是一个判断式,说白了就是一个返回bool值的函数或者仿函数。
三种写法:
class TestIndex{ public: int index; TestIndex(){ } TestIndex(int _index):index(_index){ } bool operator()(const TestIndex* t1,const TestIndex* t2){ printf("Operator():%d,%d/n",t1->index,t2->index); return t1->index < t2->index; } bool operator < (const TestIndex& ti) const { printf("Operator<:%d/n",ti.index); return index < ti.index; } }; bool compare_index(const TestIndex* t1,const TestIndex* t2){ printf("CompareIndex:%d,%d/n",t1->index,t2->index); return t1->index < t2->index; }
仿函数:仿函数就是写个类,然后重载operator(),使用就是在那些以这种需要返回bool值的函数作参数的函数里用了。
stl 中_if 后缀的函数都是需要一个谓词的, 但是stl 提供给我们的 可以自己写的谓词函数有一个限制,那就是比较的对象必须是个常量, 且必须在函数里面出现, 这样就带了一个问题, 比如说,我们需要找出保存在容器中的string 对象长度大于6的个数,按照stl 给我们提供的简单的谓词形式,我们可以定义一个谓词,比如:bool Great6(int i){return i >6;},但是如果说在你项目中我们传入的界限是个变量, 比如说找出长度大于n的个数, 这种方法就行不通了。下面有几种方法:
#include <iostream> #include <algorithm> #include <vector> #include <functional> using namespace std; /* 方法一 *对应内置对象,函数里面处理的是常数 * 比如:找出容器里面大于6的数的个数 **********************************/ bool Great6(int i) { return i >6; } bool Great10(int i) { return i > 10; } /*方法二 *利用函数对象,封装类,有特定名字叫仿函数,重载operator() * 找出容器里面大于给定数的个数,比如说找出大于8的个数 *****************************************************/ class GreatInt { public: GreatInt(int i): m_i(i){} bool operator() (int i) { return i >m_i; } private: int m_i; }; /*方法三 *利用函数对象的函数适配器 *参数n表示比较的数 ***************************/ int GreatN(vector<int>::iterator beg, vector<int>::iterator end, int n) { return count_if(beg, end, bind2nd(greater<int>(), n)); } int main() { vector<int> ivec; for(int i =0 ; i != 10; ++i) ivec.push_back(i); int iFind = 11; cout<<"第一种方法输出结果:"<<endl; int iCount1 = count_if(ivec.begin(), ivec.end(), Great6); cout<<iCount1<<endl; iCount1 = count_if(ivec.begin(), ivec.end(), Great10); cout<<iCount1<<endl; int iCount2; cout<<"第二种方法输出结果:"<<endl; iCount2 = count_if(ivec.begin(), ivec.end(), GreatInt(6)); cout<<iCount2<<endl; iCount2 = count_if(ivec.begin(), ivec.end(),GreatInt(10)); cout<<iCount2<<endl; cout<<"第三种方法输出结果:"<<endl; cout<<GreatN(ivec.begin(), ivec.end(), 6)<<endl; cout<<GreatN(ivec.begin(), ivec.end(), 10)<<endl; return 0; }