概述
文章目录
- 1 函数对象
- 1.1 函数对象的概念
- 1.2 函数对象使用
- 2 谓词
- 2.1 谓词的概念
- 2.2 一元谓词
- 2.3 二元谓词
- 3 内建函数对象
- 3.1 内建函数对象的基本概念
- 3.2 算术仿函数
- 3.3 关系仿函数
- 3.4 逻辑仿函数
1 函数对象
1.1 函数对象的概念
函数对象/仿函数:重载函数调用操作符operator()
的类的对象。使用重载的()
时,行为类似函数调用,亦称仿函数。
本质:函数对象/仿函数本质是一个类,而不是函数。
1.2 函数对象使用
调用方式:函数对象名(参数)
特点:
(1)函数对象使用时,类似于普通函数的调用, 可包含参数和返回值;
(2)函数对象可具有自己的内部状态(本质是类对象,可包含成员属性);
(3)函数对象可作为函数的参数传递,且仍支持函数对象/仿函数的调用方式。
注:函数对象/仿函数的使用方式很灵活,可包含不同类型的参数列表和返回值。
示例1:函数对象使用时,类似于普通函数的调用, 可包含参数和返回值
#include <iostream>
using namespace std;
/* 函数对象使用时,类似于普通函数的调用, 可包含参数和返回值 */
class MyAdd {
public:
//重载函数调用运算符()
int operator()(int a, int b) {
return a + b;
}
};
int main() {
//创建函数对象
MyAdd myAdd;
//调用函数对象
cout << myAdd(1, 2) << endl; //3
return 0;
}
示例2:函数对象可具有自己的内部状态;函数对象可作为函数的参数传递。
#include <iostream>
using namespace std;
/* 函数对象可具有自己的内部状态(本质是类对象,可包含成员属性) */
class Printer {
public:
//成员变量记录函数对象的内部状态
int count;
Printer() {
//初始化成员变量(即初始化函数对象的内部状态)
this->count = 0;
}
//重载函数调用运算符()
void operator() (string text){
cout << text << endl;
count++; //更新函数对象的内部状态
}
};
/* 函数对象可作为函数的参数传递 */
void func(Printer &printer, string text) {
//作为函数的参数传递时,仍支持函数对象/仿函数的调用方式
printer(text);
}
int main() {
Printer printer;
//调用函数对象
printer("Hello Cpp!");
printer("Hello Cpp!");
printer("Hello Cpp!");
//查看函数对象的内部状态
cout << "函数对象的调用次数:" << printer.count << endl; //3
//函数对象作为函数的参数传递
func(printer, "Cheer Up!"); //Cheer Up!
return 0;
}
2 谓词
2.1 谓词的概念
谓词:返回值类型为bool类型
的仿函数。
一元谓词
:operator()
的形参列表只包含一个参数。
二元谓词
:operator()
的形参列表包含两个参数。
注1:只有返回值类型为bool类型的仿函数,称为谓词。返回值类型为其它类型的仿函数,不是谓词。
注2:谓词对应STL源码中的class _Pr
类。
当STL内置函数需要_Pr _Pred
(谓词)类型的参数时,可传入:
①函数对象,即函数对象类名 对象名;
②匿名函数对象,即函数对象类名()
③回调函数名
④匿名函数(lambda表达式),即[](..){..}
仿函数/函数对象-实现自定义排序:
//函数对象/仿函数
class MyCompare {
public:
//重载函数调用运算符()
bool operator()(int val1, int val2) {
//return val1 < val2; //升序排序
return val1 > val2; //降序排序
}
};
//使用仿函数/函数对象,按自定义规则排序
MyCompare mc;
sort(vec.begin(), vec.end(), mc); //函数对象mc
sort(vec.begin(), vec.end(), MyCompare()); //匿名函数对象MyCompare()
回调函数-实现自定义排序:
//回调函数
bool myCompare(int val1, int val2){
//return val1 < val2; //升序排序
return val1 > val2; //降序排序
}
//使用回调函数,按自定义规则排序
sort(vec.begin(), vec.end(), myCompare);
匿名函数(lambda表达式)-实现自定义排序:
//使用匿名函数(lambda表达式),按自定义规则排序
sort(vec.begin(), vec.end(), [](int val1, int val2) {return val1 > val2;});
2.2 一元谓词
示例:查找大于5的元素(一元谓词、回调函数)
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
//仿函数:大于5的值
class GreaterThanFive {
public:
//重载函数调用运算符
bool operator()(int val) {
return val > 5; //大于5时返回true
}
};
//回调函数:大于5的值
bool greaterthanfive(int val) {
return val > 5; //大于5时返回true
}
int main() {
vector<int> v;
v.push_back(3);
v.push_back(2);
v.push_back(0);
v.push_back(5);
v.push_back(9);
//iterator find_if(iterator begin, iterator end, _Pr _Pred)
//_Pr类型:可传入函数对象或回调函数名
//1.传入匿名函数对象
vector<int>::iterator it = find_if(v.begin(), v.end(), GreaterThanFive());
//2.传入函数对象
//GreaterThanFive gt;
//vector<int>::iterator it = find_if(v.begin(), v.end(), gt);
//3.传入回调函数名
//vector<int>::iterator it = find_if(v.begin(), v.end(), greaterthanfive); //回调函数
if (it != v.end()) {
cout << "查找到大于5的元素:" << *it << endl;
}
else {
cout << "未查找到大于5的元素" << endl;
}
return 0;
}
2.3 二元谓词
示例:自定义排序(二元谓词、回调函数)
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
//打印vector元素的函数模板
template<typename T>
void printVector(vector<T>& v) {
//for循环遍历
for (typename vector<T>::iterator it = v.begin(); it != v.end(); it++) {
cout << (*it) << " ";
}
cout << endl;
}
//回调函数-实现自定义排序
bool myCompare(int val1, int val2) {
return val1 > val2; //降序排序
//return val1 < val2; //升序排序
}
//仿函数-实现自定义排序
class MyCompare {
public:
//重载函数调用运算符
bool operator()(int val1, int val2) {
return val1 > val2; //降序排序
//return val1 < val2; //升序排序
}
};
int main() {
vector<int> v;
v.push_back(6);
v.push_back(3);
v.push_back(9);
v.push_back(1);
v.push_back(7);
cout << "排序前:" << endl;
printVector<int>(v); //6 3 9 1 7
//1.回调函数实现自定义排序:
//cout << "回调函数实现自定义排序:" << endl;
//sort(v.begin(), v.end(), myCompare); //回调函数名
//printVector<int>(v); //9 7 6 3 1
//2.函数对象/仿函数实现自定义排序:
//cout << "函数对象/仿函数实现自定义排序:" << endl;
//sort(v.begin(), v.end(), MyCompare()); //匿名函数对象
//printVector<int>(v); //9 7 6 3 1
//3.匿名函数(lambda表达式)实现自定义排序:
//cout << "匿名函数(lambda表达式)实现自定义排序:" << endl;
sort(v.begin(), v.end(), [](int val1, int val2) {return val1 > val2;}); //匿名函数(lambda表达式)
printVector<int>(v); //9 7 6 3 1
return 0;
}
3 内建函数对象
3.1 内建函数对象的基本概念
STL提供了内建函数对象,底层源码重载函数调用运算符operator()
,主要分为3类。
(1)算术仿函数
:实现四则运算;
(2)关系仿函数
:实现关系比较,如大于小于、相等不相等。
(3)逻辑仿函数
:实现逻辑运算,如与或非运算。
使用方法:
内建函数对象(仿函数的对象),使用方法与一般函数完全相同,需包含头文件 #include<functional>
。
3.2 算术仿函数
算术仿函数:实现四则运算。取反仿函数negate
是一元运算,其它均为二元运算。
仿函数原型:
template<class T> T plus<T>
:加法仿函数
template<class T> T minus<T>
:减法仿函数
template<class T> T multiplies<T>
:乘法仿函数
template<class T> T divides<T>
:除法仿函数
template<class T> T modulus<T>
:取模仿函数
template<class T> T negate<T>
:取反仿函数
示例:算术仿函数的使用
#include <iostream>
using namespace std;
#include <functional> //内建函数对象的头文件
int main() {
/* 一元运算 */
//取反运算
negate<int> neg;
cout << neg(5) << endl; //-5
/* 二元运算 */
//加法运算
plus<double> p;
cout << p(3.33, 6.66) << endl; //9.99
return 0;
}
3.3 关系仿函数
关系仿函数:实现关系比较。
仿函数原型:
template<class T> bool equal_to<T>
:等于。
template<class T> bool not_equal_to<T>
:不等于。
template<class T> bool greater<T>
:大于,匿名对象greater<T>()
可用于降序排序。
template<class T> bool greater_equal<T>
:大于等于。
template<class T> bool less<T>
:小于,匿名对象less<T>()
默认用于升序排序。
template<class T> bool less_equal<T>
:小于等于。
示例:内建函数对象实现降序排序
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
#include <functional> //内建函数对象的头文件
//打印vector元素的函数模板
template<typename T>
void printVector(vector<T>& v) {
//for循环遍历
for (typename vector<T>::iterator it = v.begin(); it != v.end(); it++) {
cout << (*it) << " ";
}
cout << endl;
}
//自定义仿函数
class MyCompare {
public:
bool operator()(int v1, int v2) {
//降序排序
return v1 > v2;
}
};
int main() {
vector<int> v;
v.push_back(6);
v.push_back(3);
v.push_back(9);
v.push_back(1);
v.push_back(7);
printVector<int>(v); //6 3 9 1 7
//自定义仿函数实现降序排序
//sort(v.begin(), v.end(), MyCompare());
//printVector<int>(v); //9 7 6 3 1
//内建函数对象实现降序排序:greater<int>()
sort(v.begin(), v.end(), greater<int>());
printVector<int>(v); //9 7 6 3 1
return 0;
}
3.4 逻辑仿函数
逻辑仿函数:实现逻辑运算。
注:逻辑仿函数的实际应用较少,了解即可。
仿函数原型:
template<class T> bool logical_and<T>
:逻辑与
template<class T> bool logical_or<T>
:逻辑或
template<class T> bool logical_not<T>
:逻辑非
示例:
#include <iostream>
using namespace std;
#include <vector>
#include <functional>
#include <algorithm>
//打印vector元素的函数模板
template<typename T>
void printVector(vector<T>& v) {
//for循环遍历
for (typename vector<T>::iterator it = v.begin(); it != v.end(); it++) {
cout << (*it) << " ";
}
cout << endl;
}
int main(){
vector<bool> v;
v.push_back(true);
v.push_back(false);
v.push_back(true);
v.push_back(false);
printVector<bool>(v); //1 0 1 0
/* 逻辑非仿函数 */
vector<bool> vec;
//指定vec的容器大小为v
vec.resize(v.size());
//将容器v的元素搬运至vec中,且执行逻辑非运算
transform(v.begin(), v.end(), vec.begin(), logical_not<bool>());
printVector<bool>(vec); //0 1 0 1
return 0;
}
最后
以上就是落后服饰为你收集整理的C++ STL(十):函数对象/仿函数(函数对象、谓词、内建函数对象)1 函数对象2 谓词3 内建函数对象的全部内容,希望文章能够帮你解决C++ STL(十):函数对象/仿函数(函数对象、谓词、内建函数对象)1 函数对象2 谓词3 内建函数对象所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复