函数对象
重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象,也叫仿函数(functor)其实就是重载"()"操作符,使得类对象可以像函数那样调用。
注意
1.函数对象(仿函数是一个类,不是一个函数)。
2.函数对象(仿函数)重载了"()"操作符使得它可以像函数一样调用。。
分类假定某个类有一个重载的 operator(),而且重载的 operator()要求获取一个参数,我们就将这个类称为"一元仿函数(unary functor);相反,如果重载的 operator()要求获取两个参数,就将这个类称为 二元仿函数(binary functor )。
函数对象的作用主要是什么?STL 提供的算法往往都有两个版本,其中一个版本表现出最常用的某种运算 另一版本则允许用户通过template参数的形式来指定所要采取的策略。
总结
1.函数对象通常不定义构造函数和析构函数,所以在构造和析构时不会发生任何问题,避免了函数调用的运行时问题。·
2、函数对象超出普通函数的概念,函数对象可以有自己的状态。
3、函数对象可内联编译,性能好。用函数指针几乎不可能,
4、模板函数对象使函数对象具有通用性,这也是它的优势之一
#include <iostream>
#include <algorithm>
using namespace std;
//仿函数
class Person
{
public:
void operator()(int num)
{
cout << num << endl;
}
};
void test()
{
//person是一个类
Person sss;
sss(222); //仿函数的调用
Person()(3333);//使用了匿名对象
}
int main()
{
test();
}
函数对象已经超出了普通函数的概念 内部可以保存状态
函数对象可以作为参数传递
#include <iostream>
#include <algorithm>
using namespace std;
//仿函数
class Person
{
public:
void operator()(int num)
{
cout << num << endl;
count++;
}
int count = 0;
};
//函数对象不同于普通函数 可以记录次数
void test01()
{
Person sss;
sss(111);
sss(222);
sss(333);
sss(444);
cout << "调用次数" << sss.count << endl;
}
//函数对象作为值传递
void test02(Person sss, int num)
{
sss(num);
}
int main()
{
test01();
test02(Person(),555); //通过匿名对象
}
谓词
普通函数或函数对象重载() 返回值为bool
适配器
函数的是适配器
1.包含头文件 functional
2.绑定数据 bind2nd(绑定的为第二个参数 ) 这是仿函数需要俩个数据 仿函数一个数据无需绑定
3.仿函数需要继承binary_function<参数1,参数2,返回值类型>
4.仿函数需要加const修饰operater()
5.bind1st绑定的为仿函数中的第一个参数
#include "iostream"
#include "functional"
#include <vector>
#include <algorithm>
using namespace std;
void peint(int aa)
{
cout << aa << endl;
}
class peint02:public binary_function<int,int,void>
{
public:
void operator()(int aa, int num)const
{
cout << aa + num << endl;
}
};
void test()
{
vector<int> a;
a.push_back(10);
a.push_back(20);
a.push_back(30);
a.push_back(40);
int num;
cin >> num;
for_each(a.begin(), a.end(), peint);//注意括号<>里面填写仿函数不需要括号
for_each(a.begin(), a.end(), bind2nd(peint02(),num));//而在函数调用的()里 普通函数变为回调函数 仿函数救赎隐式调用
}
int main()
{
test();
}
取反是适配器
1.一元取反适配器 not1
2.继承unary_function<参数类型1,返回值>
3.const修饰operator()
4.二元取反适配器 not2
#include "iostream"
#include "functional"
#include <vector>
#include <algorithm>
using namespace std;
class Less :public unary_function<int, bool>
{
public:
bool operator()(int num)const
{
return num > 5;
}
};
void test()
{
vector<int> a;
for (int i = 0;i < 10;i++)
{
a.push_back(i);
}
//找出大于5的数
vector<int>::iterator v = find_if(a.begin(), a.end(), bind2nd(greater<int>(), 5));
if (v != a.end())
{
cout << *v << endl;
}
//找出小于5的数
//vector<int>::iterator s = find_if(a.begin(), a.end(), not1(bind2nd(greater<int>(), 5))); //利用内建函数
vector<int>::iterator s = find_if(a.begin(), a.end(), not1(Less())); //利用仿函数
if (s != a.end())
{
cout << *s << endl;
}
}
int main()
{
test();
}
函数指针适配器
1.将函数指针适配为函数对象
void add(int num, int start)
{
cout << num + start << endl;
}
void test()
{
vector<int>a;
for (int i = 0;i < 10;i++)
{
a.push_back(i);
}
//函数指针适配器
//ptr_fun
for_each(a.begin(), a.end(), bind2nd(ptr_fun(add), 100));
}
int main()
{
test();
}
成员函数适配器
#include "iostream"
#include "functional"
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
class Person
{
public:
Person(string name, int age)
{
my_age = age;
my_name = name;
}
void display() const
{
cout << "名字" << my_name << " " << "年龄" << my_age << endl;
}
private:
string my_name;
int my_age;
};
void test()
{
vector<Person>a;
Person p1("aaa", 15);
Person p2("sss", 24);
Person p3("axxxaa", 54);
Person p4("hgf", 45);
a.push_back(p1);
a.push_back(p2);
a.push_back(p3);
a.push_back(p4);
//利用类成员模板
//mem_fun_ref
for_each(a.begin(), a.end(), mem_fun_ref(&Person::display));
}
int main()
{
test();
}