函数对象

函数对象

重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象。又称仿函数

函数对象与函数指针相比,有两个优点:第一是编译器可以内联执行函数对象的调用;第二是函数对象内部可以保持状态。

函数对象类型 :函数对象一般都是应用在C++ STL容器中,泛型算法当中,智能指针当中,绑定器当中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <iostream>
using namespace std;
//示例1
int sum(int a,int b)
{
return a+b;
}
//函数对象类型 函数对象一般都是应用在C++ STL容器中,泛型算法当中,智能指针当中,绑定器当中
class Sum
{
public:
int operator()(int a,int b)
{
return a+b;
}
};

int main1()
{
cout<<sum(1,2)<<endl;
Sum sum1; //函数对象:对象有operator()运算符的重载函数
//sum1.operator()(1,2)
cout<<sum1(1,2)<<endl;
return 0;
}


//示例二
int mygreat(int a,int b)
{
return a>b;
}
int myless(int a,int b)
{
return a<b;
}
template<typename T>
class mygreat1
{
public:
int operator()(T a,T b) const
{
return a>b;
}
};
template<typename T>
class myless1
{
public:
int operator()(T a,T b) const
{
return a<b;
}
};
template<typename T,typename Compare>
T mycompare(T a,T b,Compare cmp)
{
return cmp(a,b);
}
int main()
{
cout<<mycompare(10,20,&mygreat)<<endl;
cout<<mycompare(10,20,&myless)<<endl;

cout<<mycompare(10,20,mygreat1<int>())<<endl;//调用了()运算符重载函数
cout<<mycompare(10,20,myless1<int>())<<endl;
return 0;
}

利用库里面的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <iostream>
#include <functional> //包含了库里面的函数对象类型
#include <map>
#include <string>
#include <queue>
#include <algorithm> //泛型算法
using namespace std;

template<typename T,typename Compare>
T mycompare(T a,T b,Compare cmp)
{
return cmp(a,b);
}
int main()
{
cout<<mycompare(10,20,greater<int>())<<endl;
cout<<mycompare(10,20,less<int>())<<endl;

map<int,string>vis;
vis.insert({123,"aaa"});
vis.insert({345,"bbb"});
vis.insert({678,"ccc"});
for(auto &it : vis)
cout<<it.first<<" "<<it.second<<endl;

map<int,string,greater<int> >vis1;
vis1.insert({123,"aaa"});
vis1.insert({345,"bbb"});
vis1.insert({678,"ccc"});
for(auto &it : vis1)
cout<<it.first<<" "<<it.second<<endl;
//默认大根堆
priority_queue<int>q;
q.push(23);
q.push(42);
q.push(12);
while(!q.empty())
{
cout<<q.top()<<" ";
q.pop();
}
cout<<endl;
//改造成小根堆
priority_queue<int,vector<int>,greater<int> >p;
p.push(23);
p.push(42);
p.push(12);
while(!p.empty())
{
cout<<p.top()<<" ";
p.pop();
}
cout<<endl;

vector<int>a={1,35,45,21,31};
for(auto &v:a)
cout<<v<<" ";
cout<<endl;
sort(a.begin(),a.end());
for(auto &v:a)
cout<<v<<" ";
cout<<endl;
sort(a.begin(),a.end(),greater<int>());
for(auto &v:a)
cout<<v<<" ";
cout<<endl;
return 0;
}

lambda表达式

在C++11以前,函数对象使用起来比较复杂,不灵活,所以C++11开始支持更轻量级的函数对象。

lambda表达式:只关注operator()的功能实现

1
2
3
[捕获外部的变量] (参数列表,对应operator()的参数列表)->返回值{
lambda表达式的代码
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <bits/stdc++.h>

using namespace std;

int main()
{
vector<int>a={1,35,45,21,31};
for(auto &v:a)
cout<<v<<" ";
cout<<endl;
sort(a.begin(),a.end(),[](int a,int b)->bool{return a<b;});
for(auto &v:a)
cout<<v<<" ";
cout<<endl;
sort(a.begin(),a.end(),[](int a,int b)->bool{return a>b;});
for(auto &v:a)
cout<<v<<" ";
cout<<endl;
for_each(a.begin(),a.end(),[](int a){
if(a%2==0)
cout<<a<<" ";
});
cout<<endl;
return 0;
}

泛型算法

1
2
3
4
5
6
7
//平时写码时常用的泛型算法
sort()//排序
max(),min()//取最大最小
reverse()//翻转
binary_search()//二进制查找,前提是升序的
remove()//移除,但是把元素放到数组的后面并不是清除
unique()//去重,前提是有序的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <bits/stdc++.h>
using namespace std;
int main()
{
vector<int>vec={12,5,6,14,2,2,3};
sort(vec.begin(),vec.end());
for_each(vec.begin(),vec.end(),[](int a){cout<<a<<" ";});
cout<<endl;

sort(vec.begin(),vec.end(),[](int a,int b)->bool{return a>b;});
for_each(vec.begin(),vec.end(),[](int a){cout<<a<<" ";});
cout<<endl;

auto it=find(vec.begin(),vec.end(),3);
cout<<(it==vec.end()?"3 not find":"3 find")<<endl;
//二分查找 只能升序
reverse(vec.begin(),vec.end());
cout<<binary_search(vec.begin(),vec.end(),3)<<endl;
//4按序插入vec,第一个大于5的元素
auto it1=find_if(vec.begin(),vec.end(),[](int val)->bool{return val>4;});
vec.insert(it1,4);
for_each(vec.begin(),vec.end(),[](int a){cout<<a<<" ";});
cout<<endl;

//unique去重
vec.erase(unique(vec.begin(),vec.end()),vec.end());
unique(vec.begin(),vec.end());
for_each(vec.begin(),vec.end(),[](int a){cout<<a<<" ";});
}