• STL函数对象---C++


    在这里插入图片描述

    1.函数对象

    1.1 函数对象概念

    概念:

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

    本质:

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

    1.2 函数对象使用

    特点:

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

    示例1:

    class Mysub
    {
    public:
    	int operator()(int v1, int v2)
    	{
    		return v1 - v2;
    	}
    };
    
    void Print(Mysub ms)
    {
    	cout << ms(99, 77) << endl;
    }
    void test01()
    {
    	//函数对象在使用时,可以像普通函数那样调用, 可以有参数,可以有返回值
    	Mysub ms;
    	cout << ms(100, 50) << endl;
    
    	int ret = ms(99, 88);
    	cout << ret << endl;
    
    	//函数对象可以作为参数传递
    	Print(ms);
    }
    
    • 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

    输出:

    50
    11
    22

    示例2:

    class MyPrint
    {
    public:
    	MyPrint()
    	{
    		count = 0;
    	}
    	void operator()(string test)
    	{
    		cout << test << endl;
    		count++; //统计使用次数
    	}
    
    	int count; //内部自己的状态
    };
    void test02()
    {
    	MyPrint myPrint;
    	myPrint("hello world");
    	myPrint("hello world");
    	myPrint("hello world");
    	myPrint("hello world");
    	myPrint("hello world");
    
    	cout << "myPrint调用次数为: " << myPrint.count << endl;
    }
    
    • 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

    输出:

    hello world
    hello world
    hello world
    hello world
    hello world
    myPrint调用次数为: 5

    2.谓词

    2.1 谓词概念

    概念:

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

    2.2 一元谓词

    示例:

    #include 
    #include 
    class Greater
    {
    public:
    	Greater(int val)
    	{
    		count = val;
    	}
    	bool operator()(int vall)//返回值为bool类型,operator()接受一个参数:一元谓词
    	{
    		return vall > count;//大于count的数
    	}
    
    	int count; //内部自己的状态
    };
    void test03()
    {
    	vector<int> v;
    	for (int i = 1; i <= 100; i++)
    	{
    		v.push_back(i);
    	}
    
    	//find_if:按条件查找
    	//若找到返回所在位置;若找不到则返回end()
    	vector<int>::iterator it = find_if(v.begin(), v.end(), Greater(55));//Greater(55)匿名对象
    	//查找大于55的数,若有则打印
    	if (it == v.end()) {
    		cout << "没找到!" << endl;
    	}
    	else {
    		cout << "找到:" << *it << endl;
    	}
    
    }
    
    • 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

    输出:

    找到:56

    2.3 二元谓词

    同认容器部分中vector容器降序的形式vector容器

    class MyCompare
    {
    public:
    	bool operator()(int num1, int num2)
    	{
    		return num1 > num2;
    	}
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3.内建函数对象

    3.1 内建函数对象意义

    概念:

    • STL内建了一些函数对象(用于用户调用).

    分类:

    • 算术仿函数

    • 关系仿函数

    • 逻辑仿函数

    用法:

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

    3.2 算术仿函数

    功能描述:*

    • 实现四则运算
    • 其中negate是一元运算,其他都是二元运算.

    仿函数原型:

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

    注: 无论一元还是二元运算模板列表只能给一个类型.
    示例:

    #include 
    void test05()
    {
    	//negate-取反
    	negate<int>n;
    	//negaten(99)无有参构造,这种形式不可
    	cout << n(99) << endl;
    
    	//minus-减法
    	minus<int>m;
    	cout << m(100, 99) << endl;
    
    	//modulus-取模
    	modulus<int>mo;
    	cout<<mo(100,8)<<endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    输出:

    -99
    1
    4

    3.3 关系仿函数

    功能描述:

    • 实现关系对比.

    仿函数原型:

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

    示例:

    void test06()
    {
    	vector<int> v;
    
    	v.push_back(10);
    	v.push_back(30);
    	v.push_back(50);
    	v.push_back(40);
    	v.push_back(20);
    
    	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
    		cout << *it << " ";
    	}
    	cout << endl;
    
    	//自己实现仿函数,使得降序排列
    	//之间所用:sort(v.begin(), v.end(), MyCompare());需要自定义仿函数
    	//STL内建仿函数  大于仿函数
    	sort(v.begin(), v.end(), greater<int>());
    
    	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
    		cout << *it << " ";
    	}
    	cout << endl;
    }
    
    • 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

    10 30 50 40 20
    50 40 30 20 10

    对sort函数转到定义:
    在这里插入图片描述

    可见,sort函数默认为升序是因为调用了关系仿函数less,而想要改变排序顺序也可调用内置仿函数.

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

    3.4 逻辑仿函数

    功能描述:

    • 实现逻辑运算

    函数原型:

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

    示例1:

    void test07()
    {
    	logical_and<int>l_a;
    	if (l_a(9, -1))//两个参数都为真(即都不为0)则返回true
    		cout << "yes" << endl;
    	else
    		cout << "no" << endl;
    
    	logical_or<int>l_o;
    	if (l_o(1,0))//两个参数只要一个为真则返回true
    		cout << "yes" << endl;
    	else
    		cout << "no" << endl;
    
    	logical_not<int>l_n;
    	if (l_n(99))//为真则返回假,为假则返回真
    		cout << "yes" << endl;
    	else
    		cout << "no" << endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    yes
    yes
    no

    示例2:

    void test08()
    {
    	vector<bool> v;
    	v.push_back(true);
    	v.push_back(false);
    	v.push_back(true);
    	v.push_back(false);
    
    	for (vector<bool>::iterator it = v.begin(); it != v.end(); it++)
    	{
    		cout << *it << " ";
    	}
    	cout << endl;
    
    	//逻辑非  将v容器搬运到v2中,并执行逻辑非运算
    	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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    输出:

    1 0 1 0
    0 1 0 1

    在这里插入图片描述

  • 相关阅读:
    Go并发编程和调度器
    QT笔记——QT类反射机制简单学习
    ioctl cmd 不能等于 2 的小问题
    Asp-Net-Core开发笔记:FrameworkDependent搭配docker部署
    IDEA集成Apipost Helper实现一键部署接口(避免参数注释)
    基于ROS的机器人模型建立及3D仿真【物理/机械意义】
    拍摄花絮丨《巴渝小将》走进四川·五华山旅游区拍摄圆满成功!
    Win10安装TensorRT
    基于JavaSpringBoot+Vue+uniapp微信小程序实现鲜花商城购物系统
    知识蒸馏3:YOLOV5项目准备
  • 原文地址:https://blog.csdn.net/weixin_63685622/article/details/136432857