首页 理论教育 STC++的仿函数-C++ STL(标准模板库)精解

STC++的仿函数-C++ STL(标准模板库)精解

时间:2023-10-25 理论教育 版权反馈
【摘要】:仿函数是采用第一种方式:值传递。算法并不会改变随参数而来的仿函数的状态。若希望能够以引用的方式传递仿函数,则需要在调用算法时明确表示仿函数型别是引用型别。例13-2例13-2的执行结果为:本例是以仿函数产生一个整数序列。例13-3例13-3的执行结果为:3.算法for_each()的返回值若使用算法for_each(),则不必实例化仿函数的“引用计数版本”来存取最终状态。

STC++的仿函数-C++ STL(标准模板库)精解

程序员通常以下面4种形式使用仿函数:

1)作为排序规则。

2)拥有内部状态。

3)算法for_each()的返回值

4)作为判断式。

1.仿函数作为排序规则

仿函数可以将已序的数据放入容器中。使用通常的运算符“operator<”有时不能对这些元素排序,因此需要自定义特别的规则来实现排序的目的,而仿函数可以作为排序规则,详见例13-1。

例13-1

例13-1的执行结果为:

例13-1使用了仿函数类person_sort_rule。该类定义了operator()函数。该函数对输入的数据的lastname字段进行比较。所有元素以此作为排序规则进行排序。若以一般的函数作为排序规则,则比较困难。由于set具有自动排序性,这是不能避免的,但程序员可以设计自己的排序规则。

2.仿函数可以拥有内部状态

仿函数还可以使程序在同一时刻拥有多个状态。函数传递数值的方式也有两种:通过值传递;通过引用传递。仿函数是采用第一种方式:值传递。算法并不会改变随参数而来的仿函数的状态。仿函数参数采用“传递值”方式的好处是可以传递常量或临时表达式;缺陷是无法改变仿函数的状态。算法可以改变仿函数的状态,但无法存取或改变其最终状态,改变的仅仅是仿函数的副本。有时需要存取最终状态,其关键是怎样从算法中获取结果。

从使用仿函数的算法中获取结果或反馈的方法通常有两种:

1)以引用的方式传递仿函数。若希望能够以引用的方式传递仿函数,则需要在调用算法时明确表示仿函数型别是引用型别。

2)使用for_each()算法的返回值。

下面以例13-2来说明上述知识点。

例13-2

例13-2的执行结果为:(www.xing528.com)

本例是以仿函数产生一个整数序列。当仿函数的运算符operator()被调用时,函数会返回整数值并累加1。可通过构造函数的参数指定初始值。例13-2还使用了generate()和gen-erate_n()算法。这两个算法的作用是:产生数值用以写入群集内。在使用仿函数sequence()时,均使用了初始参数,该初始参数可作为产生序列的初始值。算法generator_n()会连续n次改写元素值,产生n个元素。例如,

上述语句会产生以42为起始值的整数序列。

通过修改operator()可以产生更加复杂的序列。例如,

上述程序的执行结果为:

若要实现以引用的方式传递函数读者可将例13-2修改为例13-3。

例13-3

例13-3的执行结果为:

3.算法for_each()的返回值

若使用算法for_each(),则不必实例化仿函数的“引用计数版本”来存取最终状态。算法for_each()有其独门绝技,这是其他算法所没有的,即可以返回其仿函数。通过算法for_each()的返回值可以获取仿函数的状态,详见例13-4。

例13-4

例13-4的执行结果为:

在语句for_each(col.begin(),col.end(),MeanV())中,MeanV()产生一个反函数用于记录元素数量,并计算所有元素的总和。此仿函数传递给算法for_each(),后者会针对容器内每个元素调用仿函数。而返回的仿函数被赋值给mv。调用仿函数的成员函数value(),即可获取相应的平均值了。

4.判断式可返回仿函数的状态

所谓判断式,即返回布尔值的一个函数或仿函数。对于STL来说,并不是所有返回布尔值的函数是合法的判断式(谓词)。这样会导致很多意想不到的结果。

例13-5

例13-5的执行结果为:

例13-5中使用了一个仿Nth()函数,当被重复调用时,此仿函数会返回true。若将其传递给算法remove_if()时,此算法会将所有符合条件的元素删除。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈