STL - 函数对象

STL - 函数对象

一、函数对象
1.概念
  • 重载函数调用操作符的类,其对象常成为函数对象
  • 函数对象使用重载的()时,行为类似函数调用,也叫仿函数

本质:函数对象(仿函数)是一个类,不是一个函数

2.函数对象使用

特点:

  • 函数对象在使用时,可以像普通函数那样调用,可以有参数,可以有返回值
  • 函数对象超出普通函数的概念,函数对象可以有自己的状态
  • 函数对象可以作为参数传递
c++ 复制代码
//1
class MyAdd
{
public:
	int operator()(int v1, int v2)
	{
		return v1 + v2;
	}
};
void test01()
{
	//使用类创建对象,这里myAdd叫函数对象
	MyAdd myAdd;
	cout << myAdd(7, 8) << endl;//15
	//函数对象可以像函数一样调用
}
//2
class MyPrint
{
public:
	MyPrint()
	{
		this->count = 0;
	}
	void operator()(string test)
	{
		cout << test << endl;
		this->count++;
	}
	int count;//记录状态,内部自己的状态
};
//有自己的状态
void test02()
{
	MyPrint myPrint;
	myPrint("Hello! welcom to qingqingcaoyuan");
	cout << "myPrint调用次数:"<<myPrint.count << endl;
}

//3.函数对象可以作为参数传递
void doPrint(MyPrint& mp, string test)
{
	mp(test);
}
void test03()
{
	MyPrint myPrint;
	doPrint(myPrint, "lanyy1");
}
二、谓词
1.概念
  • 返回bool类型的仿函数称为谓词
  • 如果operator()接受一个参数,那么叫做一元谓词
  • 如果operator()接受两个参数,那么叫做二元谓词
2.一元谓词
c++ 复制代码
class GreaterFive
{
public:
	bool operator()(int val)//一元谓词
	{
		return val > 6;
	}
};
void test04()
{
	vector<int>v;
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}

	//查找容器中是否存在大于6的数字
	//find_if,条件查找算法,返回的是一个迭代器
	vector<int>::iterator it = find_if(v.begin(), v.end(), GreaterFive());//最后一个参数为匿名的函数对象,是我们要查找的条件
	if (it == v.end())
	{
		cout << "cannot find !" << endl;
	}
	else
	{
		cout << "find it ,the value is: " << *it << endl;
	}
}

函数参数若是 pred 就代表这里需要填写一个谓词

3.二元谓词
C++ 复制代码
class myCompare
{
public:
	bool operator()(int v1, int v2)
	{
		return v1 > v2;
	}
};
void test05()
{
	vector<int>v;
	v.push_back(7);
	v.push_back(8);
	v.push_back(3);
	v.push_back(6);
	v.push_back(5);

	sort(v.begin(), v.end());//默认升序排序
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;

	//改变排序规则,变为降序排序,使用函数对象(仿函数),将函数对象写在算法里面即可
	sort(v.begin(), v.end(), myCompare());//类名不是函数对象,需要+(),才是一个对象(匿名对象)
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}
三、内建函数对象
1.基本概念

概念:STL内建了一些函数对象

分类:算术仿函数、关系仿函数、逻辑仿函数

用法:

仿函数所产生的对象,用法和一般函数完全相同

使用内建函数对象,需要引入头文件 #include<functional>

2.算术仿函数

实现四则运算;其中negate是一元运算(一个操作数),其他都是二元运算。仿函数原型:

c++ 复制代码
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>       //取反仿函数

使用示例:

c++ 复制代码
void test06()
{
	//取反 一元仿函数
	negate<int>n;//数据类型为int,数据名为n
	cout << n(7) << endl;

	//二元仿函数
	plus<int>m;//默认认为传入的都是同种类型,只允许同类型相加
	cout << m(7, 8) << endl;
	//其余运算只需要改变plus即可
}
3.关系仿函数

实现关系对比的操作,函数原型:

c++ 复制代码
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>	//小于等于

示例:

c++ 复制代码
void test07()
{
	//举例大于greater
	vector<int>v;
	v.push_back(7);
	v.push_back(8);
	v.push_back(6);
	v.push_back(9);
	v.push_back(5);

	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;

	//降序排序,默认排序是升序排序,想要降序排序,需要添加一个bool类型的谓词,默认是小于less
	//sort(v.begin(), v.end(), myCompare());//这是自己写的仿函数,其次可以使用编译器内建的仿函数
	sort(v.begin(),v.end(),greater<int>());//greater<int>()是内建的仿函数
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}
4.逻辑仿函数

实现逻辑运算,函数原型:

c++ 复制代码
template<class T> bool logical_and<T>	//逻辑与
template<class T> bool logical_or<T>	//逻辑或
template<class T> bool logical_not<T>	//逻辑非

示例:

c++ 复制代码
void test08()
{
	//主要举例逻辑非
	vector<bool>v;
	v.push_back(true);
	v.push_back(false);
	v.push_back(false);

	for (vector<bool>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << "   ";
	}
	cout << endl;

	//利用逻辑非取反放入另一个容器中
	vector<bool>v2;
	v2.resize( v.size());//一定要先指定空间大小
	//使用特定函数进行转换放入
	transform(v.begin(), v.end(), v2.begin(), logical_not<bool>());
	//参数列表(原始容器区间开始,原始容器区间结束,新的容器开始,谓词(需要做什么操作))
	for (vector<bool>::iterator it = v2.begin(); it != v2.end(); it++)
	{
		cout << *it << "   ";
	}
	cout << endl;
}
相关推荐
aini_lovee2 小时前
基于粒子群算法(PSO)优化BP神经网络权值与阈值的实现
神经网络·算法
木千2 小时前
Qt5.15.2安装MSVC2019编译器
开发语言·qt
专注于ai算法的踩坑小达人2 小时前
C++变量全面总结
c++·qt
仟濹2 小时前
【Java加强】1 异常 | 打卡day1
java·开发语言·python
去往火星2 小时前
Qt6 CMake 中引入 Qt Linguist 翻译功能
开发语言·qt
老鼠只爱大米2 小时前
LeetCode经典算法面试题 #230:二叉搜索树中第K小的元素(递归法、迭代法、Morris等多种实现方案详细解析)
算法·leetcode·二叉搜索树·二叉树遍历·第k小的元素·morris遍历
星期五不见面2 小时前
嵌入式学习!(一)C++学习-leetcode(21)-26/1/29
学习·算法·leetcode
阿猿收手吧!2 小时前
【C++】atmoic原子操作与并发安全全解析
开发语言·c++·安全
2501_941322032 小时前
通信设备零部件识别与检测基于改进YOLOv8-HAFB-2算法实现
算法·yolo