C++ 函数对象

本文介绍了C++中的函数对象,包括其概念——重载函数调用操作符的类的对象,以及如何创建和使用仿函数。文章还详细讲解了谓词,分为一元谓词和二元谓词,并给出了相关示例。此外,讨论了STL内置的函数对象,如关系仿函数、逻辑仿函数和算术仿函数,并提供了使用示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

函数对象

1 概念
  • 函数对象是重载函数调用操作符的类的对象,也叫仿函数
  • 函数对象可以有参数和返回值,可以作为参数传递

​ 以下代码是一个仿函数实例,可以通过重载小括号实现两个数的相加。当然,不仅可以实现加法功能,四则运算,排序,输出打印功能均可实现。

//一个仿函数实例
class FunctorAdd {
public:
	int operator()(int v1, int v2) {
        this->count += 1;//每次调用count+1
		return v1 + v2;//实际实现了括号的两个数相加
	}
    int count;//记录运行加法的次数
};

int main()
{
	FunctorAdd add;
	cout << add(10, 10) << endl;
 
}

​ 上述代码还可以发现,如果在仿函数类中设置一个能够记录状态的变量(本例中的count),我们可以根据需求记录函数对象的状态。

​ 仿函数的写法非常的灵活,也可以作为参数进行传递。如下面这段代码。doAdd()函数实现的功能即为两个数的相加。运行结果为35.

int doAdd(FunctorAdd func, int v1, int v2) {
	return func(v1, v2);
}
int main()
{
	FunctorAdd func;
	cout << doAdd(func,12, 23);
}
2 谓词
  • 返回类型为bool的仿函数称为谓词
  • operator()接受一个参数称为一元谓词
//一元谓词
class FunctorGF{
public:
	int operator()(int val) {
		return val > 5;
	}

};

int main()
{
	vector<int>v = { 1,34,2,3,43,34,23,43,2,34,343,423,42,4 };
	vector<int>::iterator iter;
	// FunctorGF()匿名函数对象,查找有没有大于5的数字
	iter=find_if(v.begin(), v.end(), FunctorGF());
	if (iter == v.end()) {
		cout << "not find" << endl;
	}
	else
		cout << "at least a number is greater than 5" << endl;
}

  • operator()接受两个参数称为二元谓词

​ 二元谓词最经典的案例就是排序了。STL中很多容器都可以加入自定义的排序规则。不妨写一个set容器的降序排列的实现方法作为二元谓词的案例。

//二元谓词
class FunctorCmp{	
public:
	int operator()(int v1,int v2)const {
		return v1 > v2;//实现降序排列
	}

};

int main()
{
	set<int,FunctorCmp>s = { 1,34,2,3,43,34,23,43,2,34,343,423,42,4 };
	set<int>::iterator iter;
	for (iter = s.begin();iter != s.end();iter++)
		cout << *iter << " ";
}

输出为:

423 343 43 42 34 23 4 3 2 1

3 内建函数对象

​ STL内建了一些函数对象,整体分为关系仿函数、逻辑仿函数和算术仿函数三类。这些仿函数所产生的对象用法和一般函数完全相同,但使用时需要引入头文件

#include <function>

3.1 关系仿函数

template bool equal_to //等于

template bool not_ equal_to //不等于

template bool greater //大于

template bool greater_equal //大于等于

template bool less //小于

template bool less_equal //小于等于

int main()
{
	vector<int> test;
	for (int i = 0;i < 10;i++) {
		test.push_back(i * 3);//0 3 6 9 12 15 18 21 24 27
	}
	sort(test.begin(), test.end(), greater<int>());//把它整成降序
	cout << "descending order:";
	for (int i = 0;i < 10;i++) {
		cout << test[i] << " ";
	}
	cout << endl;
	sort(test.begin(), test.end(), less<int>());//再把它整成升序
	cout << "increasing order:";
	for (int i = 0;i < 10;i++) {
		cout << test[i] << " ";
	}
}

输出结果

descending order:27 24 21 18 15 12 9 6 3 0
increasing order:0 3 6 9 12 15 18 21 24 27

3.2 逻辑仿函数

​ 实现与或非的逻辑运算

template bool logical_and //逻辑与

template bool logical_or //逻辑或

template bool logical_not //逻辑非

int main()
{
	vector<bool> v1 = { true, false, true, false, true };
	vector<bool> v2 = { true, true, false, false, true };
	vector<bool> res;
	res.resize(v1.size());
	cout << "raw data v1: ";
	for (int i = 0;i < 5;i++) {
		cout << v1[i] << " ";
	}
	cout << endl;
	cout << "raw data v2: ";
	for (int i = 0;i < 5;i++) {
		cout << v2[i] << " ";
	}
	cout << endl;
	cout << "logical not data: ";
	cout << endl;
	//用transform函数实现数据转化,存储在res容器中
	transform(v1.begin(), v1.end(), res.begin(), logical_not<bool>());
	for (int i = 0;i < 5;i++) {
		cout << " not " << v1[i] << " = " << res[i] << endl;
	}
	cout << "logical and data: ";
	cout << endl;
	transform(v1.begin(), v1.end(), v2.begin(), res.begin(), logical_and<bool>());
	for (int i = 0;i < 5;i++) {
		cout <<v1[i] << " and " << v2[i] << " = " << res[i] << endl;
	}
	cout << endl;
	cout << "logical or data: ";
	cout << endl;
	transform(v1.begin(), v1.end(), v2.begin(), res.begin(), logical_or<bool>());
	for (int i = 0;i < 5;i++) {
		cout << v1[i] << " or " << v2[i] << " = " <<res[i] << endl;
	}
}

输出结果:

raw data v1: 1 0 1 0 1
raw data v2: 1 1 0 0 1
logical not data:
not 1 = 0
not 0 = 1
not 1 = 0
not 0 = 1
not 1 = 0
logical and data:
1 and 1 = 1
0 and 1 = 0
1 and 0 = 0
0 and 0 = 0
1 and 1 = 1

logical or data:
1 or 1 = 1
0 or 1 = 1
1 or 0 = 1
0 or 0 = 0
1 or 1 = 1

3.3 算术仿函数

template T plus //加法仿函数

template T minus //减法仿函数

template T multiplies //乘法仿函数

template T divides //除法仿函数

template T negate //取反仿函数

class FunctorCmp{	
public:
	int operator()(int v1,int v2)const {
		return v1 > v2;//实现降序排列
	}

};

int main()
{
	plus<int>plus;
	minus<int>min;
	multiplies<int>mul;
	divides<int>div;
	negate<int>neg;
	cout << "plus functor: 13+14=" << plus(13, 14) << endl;
	cout << "minus functor: 13-14=" << min(13, 14) << endl;
	cout << "multiplies functor: 13*14=" << mul(13, 14) << endl;
	cout << "divides functor: 28/14=" << div(28, 14) << endl;
	cout << "negate functor: -20=" << neg(20) << endl;


}

输出结果:

plus functor: 13+14=27
minus functor: 13-14=-1
multiplies functor: 13*14=182
divides functor: 28/14=2
negate functor: -20=-20

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值