概念:
- 重载函数调用操作符的类,其对象被称为函数对象
- 函数对象使用重载的()时,行为类似函数调用,也叫仿函数
本质:
- 函数对象(仿函数)是一个类,不是一个函数
函数对象使用:
- 函数对象在使用时,可以像普通函数那样调用,可以有参数,可以有返回值
- 函数对象超出普通函数的概念,函数对象可以有自己的状态
- 函数对象可以作为参数传递
#include<iostream> #include<string> using namespace std; //函数对象在使用时,可以像普通函数那样调用,可以有参数,可以有返回值 class myAdd { public: int operator()(int v1, int v2) { return v1 + v2; } }; void test1() { myAdd a1; cout << a1(1, 2) << endl; } //函数对象超出普通函数的概念,函数对象可以有自己的状态 class myPrint { public: myPrint() { this->count = 0; } void operator()(string str) { cout << str << endl; count++; } int count; }; void test2() { myPrint p1; p1("A"); p1("A"); p1("A"); cout << p1.count << endl; } //函数对象可以作为参数传递 void doPrint(myPrint& mp, string str) { mp(str); } void test3() { myPrint mp; doPrint(mp, "hello"); } int main() { test1(); test2(); test3(); return 0; }
谓词
一元谓词举例
#include<iostream> #include<vector> #include<algorithm> using namespace std; class GreaterFive { public: bool operator()(int val) { return val > 5; } }; int main() { vector<int>v; for (int i = 0; i < 10; i++) { v.push_back(i); } //查找容器中大于5的元素 //GreaterFive() 匿名函数对象 vector<int>::iterator it=find_if(v.begin(), v.end(), GreaterFive()); cout << *it << endl; return 0; }
二元谓词举例
#include<iostream> #include<vector> #include<algorithm> using namespace std; class myCompare { public: bool operator()(int v1, int v2) { return v1 > v2; } }; int main() { vector<int>v; v.push_back(10); v.push_back(30); v.push_back(20); v.push_back(40); //默认sort升序排序 sort(v.begin(), v.end()); for (vector<int>::iterator it = v.begin(); it != v.end(); it++) { cout << *it << " "; } cout << endl; sort(v.begin(), v.end(), myCompare()); for (vector<int>::iterator it = v.begin(); it != v.end(); it++) { cout << *it << " "; } return 0; }
内建函数对象
STL内建了一些函数对象:
- 算术仿函数
- 关系仿函数
- 逻辑仿函数
用法:
算术仿函数
其中negate是一元运算,其他都是二元运算:
template<class T> T puls<T>
//加法template<class T> T minus<T>
//减法template<class T> T multiplies<T>
//乘法template<class T> T modulus<T>
//除法template<class T> T negate<T>
//取反
#include<iostream> #include<functional> using namespace std; int main() { //取反 negate<int>n; cout << n(50) << endl;//-50 cout << n(0) << endl;//0 //加法 只填一个模板参数,默认相同类型 plus<int>p; cout << p(10, 20) << endl; return 0; }
关系仿函数
template<class T> bool equal_to<T>
//等于template<class T> bool not_equal_to<T>
//不等于template<class T> bool greater<T>
//大于template<class T> bool greater_equal<T>
//大于等于template<class T> bool less<T>
//小于template<class T> bool less_equal<T>
//小于等于
sort默认的排序规则是从小到大,底层默认使用了less<T>
#include<iostream> #include<vector> #include<functional> #include<algorithm> using namespace std; int main() { vector<int>v; v.push_back(10); v.push_back(30); v.push_back(40); v.push_back(20); for (vector<int>::iterator it = v.begin(); it != v.end(); it++) { cout << *it << endl; } sort(v.begin(), v.end(), less<int>()); for (vector<int>::iterator it = v.begin(); it != v.end(); it++) { cout << *it << endl; } return 0; }
逻辑仿函数
template<class T> bool logical_and<T>
逻辑与template<class T> bool logical_or<T>
逻辑或template<class T> bool logical_not<T>
逻辑非
#include<iostream> #include<vector> #include<functional> #include<algorithm> using namespace std; int main() { vector<bool>v; v.push_back(true); v.push_back(false); v.push_back(true); v.push_back(false); for (vector<bool>::iterator it = v.begin(); it != v.end(); it++) { cout << *it << " "; } cout << endl; //将容器v搬运到容器v1中,并执行取反操作 vector<bool>v2; v2.resize(v.size()); //注意没有 v2.end() transform(v.begin(), v.end(), v2.begin(), logical_not<bool>()); for (vector<bool>::iterator it = v2.begin(); it != v2.end(); it++) { cout << *it << " "; } return 0; }