C++——STL标准模板库——函数对象

本文介绍了C++中的函数对象,包括其基本概念,如一元和二元谓词的使用,以及STL中提供的内建函数对象如算术仿函数、关系比较和逻辑操作。通过示例展示了如何在算法如sort、transform和for_each中应用这些函数对象进行自定义操作。
摘要由CSDN通过智能技术生成

一、基本概念

函数对象也叫仿函数,是通过一个类封装了()的重载函数,该类实例化对象就叫做函数对象。这意味着函数可以被赋值给变量,可以作为参数传递给其他函数,也可以作为返回值从函数中返回。主要用于算法的自定义行为或者回调函数等。

函数对象不仅封装了()的重载函数,还可以定义自身的成员属性用来实现更复杂的目的。

二、谓词

返回值为bool类型的()重载函数对象叫做谓词。参数列表中只需接收一个参数的叫做一元谓词,接收两个参数的叫做二元谓词。C++STL中很多算法参数列表中显示需要一个名字叫_Pred的东西,大多数情况下就是需要一个谓词。

class GreatFive {							//一元谓词
public:
	bool operator()(int value) {
		return value > 5;
	}
};
void test() {
	vector<int> v{ 1,2,3,4,5,6,7,8,9 };
	auto it = find_if(v.begin(), v.end(), GreatFive());
	cout << *it << endl;
}

代码中GreatFive就是一元谓词,it返回指向第一个大于5的元素的迭代器 。

template<class C>
void printC(const C& c) {
	for (typename C::const_iterator it = c.begin(); it != c.end(); it++) {
		cout << (*it) << " ";
	}
	cout << endl;
}

class MyCompare {							//二元谓词
public:
	bool operator()(int v1,int v2) {
		return v1 > v2;
	}
};
void test() {
	vector<int> v{ 1,3,2,5,4 };
	sort(v.begin(), v.end());
	printC(v);
	sort(v.begin(), v.end(), MyCompare());
	printC(v);
}

代码中MyCompare就是二元谓词,sort算法默认递增排序,通过MyCompare实现递减排序

三、内建函数对象

STL中提供了多种内置的函数对象,用来实现内置数据类型的基础运算、关系比较以及逻辑与、或、非,在使用内建函数时需要:#include <functional>

(一)算术仿函数

template<class T> T pluse<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>       //取反仿函数

除了取反是一元运算,其他函数对象都是二元运算

//for_each是STL提供的遍历算法,可以自定义遍历过程中的功能,需要包含algorithm,
//需要提供一个只接收一个参数的函数。

//transform函数时STL提供的复制算法,将一个容器的元素逐一复制到另一个容器,
//过程中可以自定义处理功能,需要提供一个只接收一个参数的函数,并返回该参数类型。
//所以不能直接使用modulus的()重载

void print(int&a) {											//为for_each遍历算法提供输出功能函数
	cout << a << " ";
}
int ModulusBy5(int &a) {									//为transform复制算法提供数据处置功能
	return modulus<int>()(a, 5);							//modulus仿函数
}
void test() {
	vector<int> v{ 1,2,3,4,5,6,7,8,9 };
	vector<int> v1;
	v1.resize(v.size());									//复制前需要开辟相应的空间

	for_each(v.begin(), v.end(), print); cout << endl;		//遍历v容器
	transform(v.begin(), v.end(), v1.begin(), ModulusBy5);	//将[v.begin(),v.end())内的元素逐一经过ModulusBy5处理,复制到v1
	for_each(v1.begin(),v1.end(), print);					//遍历v1容器
}

(二)关系仿函数

template<class T> bool equal_to<T>                 //等于

template<class T> bool not_equal_to<T>          //不等于

template<class T> bool greater<T>                   //大于

template<class T> bool greater_equal<T>        //大于等于

template<class T> bool less<T>                        //小于

template<class T> bool less_equal<T>             //小于等于

//sort算法是STL提供的排序算法模板函数,默认递增排序,源码中默认使用二元谓词less<>()
//当容器中存储的是自定义类型或者内置类型递减排序时需要提供其他的排序函数对象(二元谓词)
//greater<T> 是STL提供的递减排序的二元谓词
void print(int&a) {
	cout << a << " ";
}

void test() {
	vector<int>v({ 4,2,5,3,1,7,6 });
	sort(v.begin(), v.end());
	for_each(v.begin(), v.end(), print); cout << endl;
	sort(v.begin(), v.end(), greater<int>());
	for_each(v.begin(), v.end(), print); cout << endl;
}

(三)逻辑仿函数

template<class T> bool logical_and<T>;                逻辑与

template<class T> bool logical_or<T>;                   逻辑或

template<class T> bool logcial_not<T>;                  逻辑非

//利用transform将v中的bool类型经过func的处理复制到d中
//使用逻辑非内建函数对象

bool func(const bool& b) {
	return  logical_not<bool>()(b);
}
template<class T>
void print(const T& b) {
	cout << b << " ";
}
void test() {
	vector<bool>v{ true,false,true,false,true,false };
	deque<bool>d;
	d.resize(v.size());
	for_each(v.begin(), v.end(), print<bool>); cout << endl;
	transform(v.begin(), v.end(), d.begin(), func);
	for_each(d.begin(), d.end(), print<bool>);
}
  • 20
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值