19.7 C++STL标准模板库大局观-函数对象回顾、系统函数对象与范例

19.1 C++STL标准模板库大局观-STL总述、发展史、组成与数据结构谈
19.2 C++STL标准模板库大局观-容器分类与array、vector容器精解
19.3 C++STL标准模板库大局观-容器的说明和简单应用例续
19.4 C++STL标准模板库大局观-分配器简介、使用与工作原理说
19.5 C++STL标准模板库大局观-迭代器的概念和分类
19.6 C++STL标准模板库大局观-算法简介、内部处理与使用范例
19.7 C++STL标准模板库大局观-函数对象回顾、系统函数对象与范例
19.8 C++STL标准模板库大局观-适配器概念、分类、范例与总结

7.函数对象回顾、系统函数对象与范例

在这里插入图片描述

  7.1 函数对象/仿函数回顾

    上一节讲解了算法,举了几个例子,在针对sort这个算法举例的时候可以注意到,sort的第三个参数是一个函数对象(functionobjects)或者叫仿函数(functors),用来指定一个排序的规则。仿函数其实就是函数对象,只不过仿函数这个称呼比较老,新称呼是函数对象。
    这种函数对象在STL里面一般都是用来跟算法配合使用以实现一些特定的功能。换句话来说,这些函数对象主要用来服务于算法,这一点读者要明确。
    为什么要引入函数对象这种概念,就是因为它们的调用方式很统一。跟调用函数的语法是一样的,如下:
    名字(参数列表)

在这里插入图片描述
    实际上,函数对象的各种形式虽然可以细分为图19.29中的几种形式,但在叫法上可以统一叫成函数对象。

  7.2 标准库中定义的函数对象

    前面演示的都是自己写的函数对象,其实,标准库中也提供了许多可以现成拿来使用的函数对象。使用它们之前,要在.cpp源文件前面包含一个头文件:

#include <functional>

    在main主函数中加入如下代码:
    在这里,先不用管这些标准库中定义的函数对象怎样使用,先看一看都有哪些,怎样分类。下面的内容取材于官方的资料,笔者以表格形式给出,方便读者参考。

(1)算术运算类

在这里插入图片描述

(2)关系运算类

在这里插入图片描述

(3)逻辑运算类

在这里插入图片描述

(4)位运算类

在这里插入图片描述
    这里随便看一个算术运算类的函数对象,如plus<类型>(),看起来这是用来将两个参数相加。在main主函数中,找个位置输入plus并按F12键,能够看到plus到底是什么。能够观察到,这其实是一个类模板,然后里面重载了operator()。简化一下它的源码,大概如下:

template<class _Ty = void>
	struct plus
	{
	constexpr _Ty operator()(const _Ty& _Left, const _Ty& _Right) const
		{	// apply operator+ to operands
		return (_Left + _Right);
		}
	};

    看起来,plus的源码比较简单,重载operator()并在其中实现两个参数相加,仅此而已。
    所以,实例化该类模板并生成一个相关的类对象,这个对象就是可调用对象或者叫函数对象。读者理解时就理解成:是一个对象,但又可以像函数调用一样调用
    看下面这行代码:

cout << plus<int>()(4, 5) << endl;

    (1)plus 是一个实例化了的类。
    (2)类名后面加一个圆括号也就是“plus()”代表生成一个类plus的临时对象(因为plus中重载了operator(),所以这个临时对象是一个可调用对象)。
    (3)为了调用这个可调用对象,在临时对象后面,增加圆括号(),之后plus类模板的operator()中有什么参数,这个圆括号中就要有什么参数。因为plus类模板的operator()中需要两个参数,所以要写成:
    上面这行代码就是调用可调用对象,实际就是等价于执行了类plus的operator()。执行的结果是两个形参的和值,因此,上面代码的输出结果是9。

  7.3 标准库中定义的函数对象范例

    19.6.3节中演示了sort算法对一个vector容器中的数据进行从大到小排序,当时为了实现此目的专门写了一个函数——myfuncsort。其实,用系统提供的可调用对象也可以实现相同的功能,这样就没有必要书写自己的myfuncsort函数(可调用对象)了。
    在main主函数中加入如下代码:

{
	vector<int> myvector3 = { 50,15,80,30,46 };

	//数据元素从大到小排序
	sort(myvector3.begin(), myvector3.end(), greater<int>()); //最后一个参数是产生一个临时对象,这里int就是容器中的元素类型

	//数据元素从小到大排序
	sort(myvector3.begin(), myvector3.end(), less<int>());
	cout << "断点设置在这里" << endl;
}

    上述代码用到了greater()和less()两个可调用对象。读者不要忘记,这两个可调用对象在调用的时候需要两个形参,这一点和myfuncsort函数一样。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值