• 【42STL-函数对象使用详情】


    13 STL-函数对象

    13.1 函数对象

    13.1.1 函数对象概念

    概念:

    • 重载函数调用重载符的类,其对象常称为函数对象
    • 函数对象使用重载的()时,行为类似函数调用,也叫仿函数

    本质:

    函数对象(仿函数)是一个,不是一个函数

    13.1.2 函数对象使用

    特点:

    • 函数对象在使用时,可以像普通函数那样调用,可以有参数,可以有返回值
    • 函数对象超出普通函数的概念,函数对象可以有自己的状态
    • 函数对象可以作为参数传递

    示例代码:

    #include
    using namespace std;
    
    /*
    * 函数对象(仿函数)
    - 函数对象在使用时,可以像普通函数那样调用,可以有参数,可以有返回值
    - 函数对象超出普通函数的概念,函数对象可以有自己的状态
    - 函数对象可以作为参数传递
    */
    class MyAdd
    {
    public:
    	int operator()(int v1, int v2)
    	{
    		return v1 + v2;
    	}
    };
    
    //1、函数对象在使用时,可以像普通函数那样调用,可以有参数,可以有返回值
    void test11()
    {
    	MyAdd myadd;
    	cout << myadd(10,20) << endl;
    }
    
    //2、 函数对象超出普通函数的概念,函数对象可以有自己的状态
    class MyPrint
    {
    public:
    	MyPrint()
    	{
    		count = 0;
    	}
    	void operator()(string test)
    	{
    		cout << test << endl;
    		this->count++;
    	}
    	int count;  //内部自己的状态
    };
    
    void test12()
    {
    	MyPrint myprint;
    	myprint("hello world!");
    	myprint("hello world!");
    	myprint("hello world!");
    	cout << " MyPrint调用次数为:" << myprint.count << endl;
    }
    
    //3.函数对象可以作为参数传递
    void doPrint(MyPrint& mp, string s)
    {
    	mp(s);
    }
    
    void test13()
    {
    	MyPrint mp;
    	doPrint(mp,"hello C++");
    }
    
    int main()
    {
    	//test11();
    	//test12();
    	test13();
    	system("pause");
    	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
    • 69
    • 70

    运行结果:

    在这里插入图片描述

    总结:

    • 仿函数写法非常灵活,可以作为参数进行传递

    13.2 谓词

    13.2.1 谓词概念

    概念:

    • 返回bool类型的仿函数称为谓词
    • 如果operator() 接收一个参数,那么叫做一元谓词
    • 如果operator()接受两个参数,那么叫做二元谓词
    13.2.2 一元谓词

    示例代码:

    #include
    using namespace std;
    #include
    #include
    
    //仿函数 返回值类型是bool数据类型,称为谓词
    //一元谓词
    
    class GreaterFive
    {
    public:
    	bool operator()(int v)
    	{
    		return v > 5;
    	}
    };
    void test21() 
    {
    	vector<int>v;
    	for (int i = 0; i < 10; i++)
    	{
    		v.push_back(i);
    	}
    
    	//查找容器中,有没有大于5的数字
    	//匿名的函数对象
    	vector<int>::iterator it= find_if(v.begin(), v.end(), GreaterFive());
    	if (it==v.end())
    	{
    		cout << "未找到" << endl;
    	}
    	else
    	{
    		cout << "找到该元素:" << (*it) << endl;
    	}
    }
    
    int main()
    {
    	test21();
    	system("pause");
    	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

    运行结果:

    在这里插入图片描述

    总结: 参数只有一个的谓词,称为一元谓词

    13.2.3 二元谓词

    示例代码:

    #include
    using namespace std;
    #include
    #include
    //二元谓词
    void printV(vector<int>&v)
    {
    	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
    	{
    		cout << (*it) << "  ";
    	}
    	cout << endl;
    }
    
    class MyCompare
    {
    public:
    	bool operator()(int v1, int v2)
    	{
    		return v1 > v2;
    	}
    };
    
    void test31()
    {
    	vector<int>v;
    	v.push_back(20);
    	v.push_back(40);
    	v.push_back(10);
    	v.push_back(50);
    	v.push_back(30);
    	printV(v);
    
    	sort(v.begin(),v.end());
    	printV(v);
    
    	//使用函数对象,改变算法策略,变为排序规则从大到小
    	sort(v.begin(), v.end(), MyCompare());
    	printV(v);
    
    }
    
    int main()
    {
    	test31();
    	system("pause");
    	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

    在这里插入图片描述

    总结: 参数只有两个的谓词,称为二元谓词

    13.3 内建函数对象

    13.3.1 内建函数对象意义

    概念:

    • STL内建了一些函数对象

    分类:

    1. 算术仿函数
    2. 关系仿函数
    3. 逻辑仿函数

    用法:

    • 这些仿函数所产生的对象,用法和一般函数完全相同
    • 使用内建函数对象,需要引入头文件 #include

    仿函数原型:

    • template T plus //加法仿函数
    • template T minus //减法仿函数
    • template T multiplies //乘法仿函数
    • template T divides //除法仿函数
    • template T modulus //取模仿函数
    • template T negate //取反仿函数

    示例代码:

    #include
    using namespace std;
    #include //内建函数对象头文件
    
    //内建函数对象     算术仿函数
    
    //negate  一元仿函数 取反仿函数
    void test41()
    {
    	negate<int>n;
    
    	cout << n(30) << endl;
    }
    //plus 二元仿函数  加法
    void test42()
    {
    	plus<int>p; //两个数必须是同类型,进行运算
    	cout << p(20, 80) << endl;
    
    	divides<int>d;
    	cout << d(100,10) << endl;
    }
    
    int main()
    {
    	//test41();
    	test42();
    	system("pause");
    	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

    运行结果:

    在这里插入图片描述

    总结: 使用内建函数对象是,需要引入头文件 #include

    13.3.2 关系仿函数

    功能描述:

    • 实现关系对比

    仿函数原型:

    • template bool equal_to //等于
    • template bool not_equal_to //不等于
    • template bool greater //大于
    • template bool greater_equal //大于等于
    • template bool less //小于
    • template bool less_equal //小于等于

    示例代码:

    #include
    using namespace std;
    #include
    #include
    #include
    
    //内建函数对象 关系仿函数
    //大于  greater
    
    class MyCompare
    {
    public:
    	bool operator()(int v1, int v2)
    	{
    		return v1 > v2;
    	}
    };
    
    void test01()
    {
    	vector <int>v;
    	
    	v.push_back(20);
    	v.push_back(30);
    	v.push_back(10);
    	v.push_back(40);
    	v.push_back(50);
    
    	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
    	{
    		cout << (*it) << " ";
    	}
    	cout << endl;
    
    	//sort(v.begin(),v.end(),MyCompare());
    	//greater()  内建函数对象
    	sort(v.begin(),v.end(),greater<int>());
    
    	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
    	{
    		cout << (*it) << " ";
    	}
    	cout << endl;
    }
    
    int main()
    {
    	test01();
    	system("pause");
    	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

    运行结果:

    在这里插入图片描述

    总结: 关系仿函数中最常用的就是greater<> 大于

    13.3.3 逻辑仿函数

    功能描述:

    • 实现逻辑运算

    函数原型:

    • template bool logical_and //逻辑与
    • template bool logical_or //逻辑或
    • template bool logical_not //逻辑非

    示例代码:

    #include
    using namespace std;
    #include
    #include
    #include
    
    //内建函数对象  逻辑仿函数
    //逻辑非	logical_not
    void test61()
    {
    	vector<bool>v;
    	v.push_back(true);
    	v.push_back(false);
    	v.push_back(false);
    	v.push_back(true);
    
    	for (vector<bool>::iterator it = v.begin(); it != v.end(); it++)
    	{
    		cout << (*it) << "  ";
    	}
    	cout << endl;
    
    	//利用逻辑非,将容器v搬运到容器v2中,并执行取反操作
    	vector<bool>v2;
    	v2.resize(v.size());   //v2容器开辟与v一样的大小空间
    
    	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;
    	
    }
    
    int main()
    {
    	test61();
    	system("pause");
    	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

    运行结果:

    在这里插入图片描述

    总结: 逻辑仿函数实际应用较少,了解即可。

    如果对你有帮助的话,请不要忘了给我一点点点…支持 ( ^ o ^)/~

    上一篇:【41C++STL-常用容器使用案例-员工分组】

    下一篇:【43C++STL-常用算法----1、常用遍历算法】

  • 相关阅读:
    在Windows 10中开启FTP服务
    MAML:User Diverse Preference Modeling by Multimodal AttentiveMetric Learning
    CSS|02 基本选择器
    Kotlin语言的函数头学习
    做期权卖方一般会怎么选择合约?
    Vitis HLS 加法器(整数)设计
    基于MATLAB的迭代学习控制(Iterative Learning Control,ILC)算法的仿真与分析
    鸿蒙 DevEcoStudio:简单实现网络请求登录案例
    赞奇科技出席江苏828 B2B企业服务峰会,助力企业数字化转型
    常用电子元器件基础知识
  • 原文地址:https://blog.csdn.net/qq_45986997/article/details/126728083