仿函数:可以将类对象当函数一样使用,实际就是重载了“operator()”的类

class Linear
{
private:
    double slope;
    double y0;
public:
    Linear(double sl_ = 1, double y_ = 0)
        : slope(sl_), y0(y_) {}
    double operator() (double x) { return y0 + slope * x; }
}
应用:
Linear f1;
Linear f2(2.5, 10.0);
double y1 = f1(12.5);    // right_hand side is f1.operator() (12.5)
double y2 = f2(0.4);

函数适配器
 绑定适配器:bind1st、bind2nd
将n元函数对象的指定参数绑定为一个常数,得到n-1元函数对象

#include "stdafx.h"
#include<iostream>
#include<functional>
#include<algorithm>
#include<vector>
#include<numeric>
using namespace std;

template<class T>
class intgreat
{
public:
	bool operator()(const int &num,const int &num2)const
	{
		return (num > num2);
	}

};
int _tmain(int argc, _TCHAR* argv[])
{
	int array[] = { 30, 50, 70, 90, 20, 10 };
	int n = sizeof(array) / sizeof(int);
	vector<int>b(array, array + n);
	vector<int>::iterator p = find_if(b.begin(), b.end(), bind2nd(greater<int>(), 40));
if (p != b.end())
	{
		cout << "it has exit,the place is :" << distance(b.begin(), p)+1  << endl;
	}
	else
		cout << "it not exit" << endl;
	
	return 0;
}
  组合适配器:not1、not2
将指定谓词的结果取反
 函数指针适配器:ptr_fun
 将一般函数指针转换为函数对象,使之能够作为其它函数适配器的输入。
没有在类中重载()运算符,只是在主函数外声明及定义了一个普通的函数,当传入适配器时,需要进行转换,ptr_fun(f) //f是函数的名字。

倘若只是作为一个函数对象用于比较,可以只传函数名,无需进行转换。
** 在进行参数绑定或其他转换的时候,通常需要函数对象的类型信息**
例如 bind1st和bind2nd要求函数对象必须继承于binary_function类型。但如果传入的是函数指针形式的函数对象,实参传给它一个函数名,无法获得函数对象的类型信息,这时要用函数指针适配器进行一下转换。

#include <functional>
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
bool g(int x, int y) {
return x > y;
}
int main() {
int intArr[] = { 30, 90, 10, 40, 70, 50, 20, 80 };
const int N = sizeof(intArr) / sizeof(int);
vector<int> a(intArr, intArr + N);
vector<int>::iterator p;
p = find_if(a.begin(), a.end(), bind2nd(ptr_fun(g), 40));
if (p == a.end())
cout << "no element greater than 40" << endl;
else
cout << "first element greater than 40 is: " << *p << endl;
p = find_if(a.begin(), a.end(), not1(bind2nd(greater<int>(), 15)));
if (p == a.end())
cout << "no element is not greater than 15" << endl;
else
cout << "first element that is not greater than 15 is: " << *p << endl;
p = find_if(a.begin(), a.end(), bind2nd(not2(greater<int>()), 15));
if (p == a.end())
cout << "no element is not greater than 15" << endl;
else
cout << "first element that is not greater than 15 is: " << *p << endl;
return 0;
}
 成员函数适配器(将类的成员函数转化成普通的函数对象):ptr_fun、ptr_fun_ref
**对成员函数指针使用**
把n元成员函数适配为n + 1元函数对象,该函数对象的第一个参数为调用该成员函数时的目的对象,也就是需要将“object->method()”转为“method(object)”形式。将 “object->method(arg1)”转为二元函数“method(object, arg1)”。绑定适配器binder2nd的实例构造通常比较冗长,bind2nd函数用于辅助构造binder2nd,产生它的一个实例。 binder1st和bind1st,将一个具体值绑定到二元函数的第一个参数。
要使用成员函数指针时,就得有对象指针或者对象引用,这样的函数调用,就不方便方便放在某些需要函数对象作为参数的地方,这时用成员函数适配器将指向对象的指针或对象的引用转换为这个函数的参数,这样,这个函数就可以当做一个普通的函数对象来使用了。
#include <functional>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Car {
int id;
Car(int id) { this->id = id; }
void display() const { cout << "car " << id << endl; }
};
int main() {
vector<Car *> pcars;
vector<Car> cars;
for (int i = 0; i < 5; i++)
pcars.push_back(new Car(i));
for (int i = 5; i < 10; i++)
cars.push_back(Car(i));
cout << "elements in pcars: " << endl;
for_each(pcars.begin(), pcars.end(), std::mem_fun(&Car::display));
cout << endl;
cout << "elements in cars: " << endl;
for_each(cars.begin(), cars.end(), std::mem_fun_ref(&Car::display));
cout << endl;
for (size_t i = 0; i < pcars.size(); ++i)
delete pcars[i];
return 0;
}
posted on 2018-09-09 15:09  泰坦妮克号  阅读(237)  评论(0编辑  收藏  举报