$ g++ fiborand.cpp
$ ./a.out
Fibonacci random number generator
using random_shuffle and a function object
Before shuffle:
1 2 3 4 5 6 7 8 9 10
After shuffle:
6 8 5 4 3 7 10 1 9
该程序用完全不通的方法使用使用rand_shuffle。Fibonacci 发生器封装在一个类中,该类能从先前的“使用”中记忆运行结果。在本例中,类FiboRand 维护了一个数组和两个索引变量I和j。
FiboRand类继承自unary_function() 模板:
template <class Arg>
class FiboRand : public unary_function<Arg, Arg> {
Arg是用户自定义数据类型。该类还定以了两个成员函数,一个是构造函数,另一个是operator()()函数,该操作符允许random_shuffle()算法象一个函数一样“调用”一个FiboRand对象。
绑定器函数对象
一个绑定器使用另一个函数对象f()和参数值V创建一个函数对象。被绑定函数对象必须为双目函数,也就是说有两个参数,A和B。STL 中的帮定器有:
· bind1st() 创建一个函数对象,该函数对象将值V作为第一个参数A。
· bind2nd()创建一个函数对象,该函数对象将值V作为第二个参数B。
举例如下:
Listing 11. binder.cpp
#include <iostream.h>
#include <algorithm>
#include <functional>
#include <list>
using namespace std;
// Data
int iarray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
list<int> aList(iarray, iarray + 10);
int main()
{
int k = 0;
count_if(aList.begin(), aList.end(),
bind1st(greater<int>(), 8), k);
cout << "Number elements < 8 == " << k << endl;
return 0;
}
Algorithm count_if()计算满足特定条件的元素的数目。 这是通过将一个函数对象和一个参数捆绑到为一个对象,并将该对象作为算法的第三个参数实现的。 注意这个表达式:
bind1st(greater<int>(), 8)
该表达式将greater<int>()和一个参数值8捆绑为一个函数对象。由于使用了bind1st(),所以该函数相当于计算下述表达式:
8 > q
表达式中的q是容器中的对象。因此,完整的表达式
count_if(aList.begin(), aList.end(),
bind1st(greater<int>(), 8), k);
计算所有小于或等于8的对象的数目。
否定函数对象
所谓否定(negator)函数对象,就是它从另一个函数对象创建而来,如果原先的函数返回真,则否定函数对象返回假。有两个否定函数对象:not1()和not2()。not1()接受单目函数对象,not2()接受双目函数对象。否定函数对象通常和帮定器一起使用。例如,上节中用bind1nd来搜索q<=8的值:
count_if(aList.begin(), aList.end(),
bind1st(greater<int>(), 8), k);
如果要搜索q>8的对象,则用bind2st。而现在可以这样写:
start = find_if(aList.begin(), aList.end(), not1(bind1nd(greater<int>(), 6)));
你须使用not1,因为bind1nd返回单目函数。
总结:使用标准模板库 (STL)
尽管很多程序员仍然在使用标准C函数,但是这就好像骑着毛驴寻找Mercedes一样。你当然最终也会到达目标,但是你浪费了很多时间。
尽管有时候使用标准C函数确实方便(如使用sprintf()进行格式