函数对象:
重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象。一个类对象,表现出一个函数的特征,就是通过“对象名+(参数列表)”的方式使用一个类对象,如果没有上下文,完全可以把它看作一个函数对待。
这是通过重载类的operator()来实现的。
“在标准库中,函数对象被广泛地使用以获得弹性”,标准库中的很多算法都可以使用函数对象或者函数来作为自定的回调行为;
函数对象是属于类对象,能突破函数的概念,能保持调用状态信息,也叫仿函数
一元函数对象:函数参数1个;
二元函数对象:函数参数2个;
注意:函数对象必须重载 返回值 operator()(参数) , 只要重载了这个,这个类定义的对象就是函数对象。
谓词:返回值是bool,可以作为一个判断式
一元谓词 函数参数1个,函数返回值是bool类型,可以作为一个判断式
谓词可以是一个仿函数,也可以是一个回调函数。
二元谓词 函数参数2个,函数返回值是bool类型
函数对象和谓词广泛用在STL算法中。
回调函数:本质就是一个普通函数,所谓回调,就是后来写的函数也适用在之前编写的代码中。没有什么特别的,任何函数都可以是回调,只要能实现业务逻辑。回调函数主要是作为参数,这个参数是函数名,函数名是函数的入口地址,函数名可以看做是函数指针,所以回调函数作为参数,其实是函数名是入口地址,函数根据这个入口地址进去执行了函数体。
函数指针:定义好函数返回值,函数参数
实例1:
#include <iostream> using namespace std; #include <vector> #include <algorithm>
template <typename T> class Div { public: Div(const T &div) { this->div = div; } bool operator()(T &x) //一元谓词 一元函数对象 { return (x % div == 0); } private: T div; }; //一元函数对象 void main_one() { int a = 4; vector<int> v1; for (int i = 10; i < 33; i++) { v1.push_back(i); } vector<int>::iterator it; it = find_if(v1.begin(), v1.end(), Div<int>(4)); if (it == v1.end()) { cout << "没有找到" << endl; } else { cout << *it << endl; } }
template <typename T> class AddSum { public: T operator()(T t1, T t2) //二元函数对象 { return t1 + t2; } };
//二元函数对象 void main_two() { vector<int> v1, v2; vector<int> v3; v3.resize(3); v1.push_back(1); v1.push_back(2); v1.push_back(3);
v2.push_back(4); v2.push_back(5); v2.push_back(6);
transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), AddSum<int>()); for (vector<int>::iterator it = v3.begin(); it != v3.end(); ++it) { cout << *it << endl; } } //二元谓词 template <typename T>void show(T & t) //回调函数 { cout << t << " "; } template <typename T>bool _sort(T t1,T t2) //二元谓词 { return t1 < t2; } void main_two_weici() { vector<int> v1; for (int i = 0; i < 10; i++) { int tag = rand() % 100; v1.push_back(tag); } for (vector<int>::iterator it = v1.begin(); it != v1.end(); ++it) { cout << *it << " "; } cout << endl; for_each(v1.begin(), v1.end(), show<int>); cout << endl; //排序 sort(v1.begin(), v1.end(), _sort<int>); for_each(v1.begin(), v1.end(), show<int>); cout << endl; }
void main() { //main_two(); main_two_weici(); system("pause"); }
实例2
struct FuncTeacher { bool operator()(const Teacher & left, const Teacher& right) //仿函数 二元谓词 { if (left.age < right.age) { return true; } else { return false; } } }; void main14() { set<Teacher, FuncTeacher>s; //函数对象 Teacher t1("s1", 55), t2("s2", 24), t3("s3", 11), t4("s4", 54), t5("s5", 41); s.insert(t1); s.insert(t2); s.insert(t3); s.insert(t4); s.insert(t5); for (set<Teacher, FuncTeacher>::iterator it = s.begin(); it != s.end(); ++it) { cout << it->age << "-" << it->name << endl; } }
void main15() { set<Teacher, FuncTeacher> s; Teacher t1("s1", 55), t2("s2", 24), t3("s3", 11), t4("s4", 54), t5("s5", 55); pair<set<Teacher, FuncTeacher>::iterator,bool> set_pair1 = s.insert(t1); if (set_pair1.second) { cout << "插入成功" << endl; } else { cout << "插入失败" << endl; } s.insert(t2); pair<set<Teacher, FuncTeacher>::iterator, bool> set_pair5 = s.insert(t5); //已经有55了 if (set_pair5.second) { cout << "插入成功" << endl; } else { cout << "插入失败" << endl; } for (set<Teacher, FuncTeacher>::iterator it = s.begin(); it != s.end(); ++it) { cout << it->age << "-" << it->name << endl; } }
实例3
#include <iostream> using namespace std; #include <string> #include <set> #include <algorithm>
class NocompareBig_Small { public: bool operator()(const string str1, const string str2) //伪函数、二元谓词 { string _str1; _str1.resize(str1.size()); transform(str1.begin(), str1.end(), _str1.begin(), tolower);
string _str2; _str2.resize(str2.size()); transform(str2.begin(), str2.end(), _str2.begin(), tolower); return (_str1 < _str2); } }; void main() { set<string> s1; s1.insert("aaa"); s1.insert("bbb"); s1.insert("ccc"); set<string>::iterator it = s1.find("aAa"); if (it != s1.end()) { cout << "找到" << endl; } else { cout << "没找到" << endl; } set<string, NocompareBig_Small> s2; s2.insert("aaa"); s2.insert("bbb"); s2.insert("ccc"); set<string>::iterator it2 = s2.find("aAa"); if (it2 != s2.end()) { cout << "不区分大小写的 找到" << endl; } else { cout << "没找到" << endl; } system("pause"); }