什么是函数对象呢?先让我们看一个例子,需要写一个随机数生成函数RandGen,生成的随机数要小于函数参数limit。
-
int RandGen(int limit) {
-
return int(std::rand()) % limit;
-
}
代码很简单,输入limit,利用标准库STL来返回一个rand()除以limit的余数。现在改变一下要求,要求写一个没有参数的函数,返回一个随机数,这个随机数要小于limit。等等...没有参数?那怎么知道limit是多少呢?别急,使用函数对象或者叫function object可以很好地帮我们完成任务。代码如下,
-
class URandGen {
-
int limit;
-
public:
-
URandGen(int lim) : limit(lim) {}
-
int operator()() {
-
int i = int(std::rand()) % limit;
-
return i;
-
}
-
};
这里面比较特殊的就是对operator()操作符的重载,类似的操作符重载我们可以当做普通的函数来看待,第一个()就是操作符的名字,第二个()是告诉编译器这是个操作符重载操作,其实和普通函数定义用到的()是一样的。
使用URandGen的时候,先定义一个类的对象,然后调用就可以了,
-
const int MAX = 50;
-
// An integer random number generator
-
URandGen urg(MAX);
-
srand(static_cast<unsigned int>(time(0))); //Randomize
-
for (int i = 10; i > 0; i--) {
-
cout << urg() << " ";
-
}
代码中定义MAX是50,即生成的随机数不超过50,另外还调用了函数srand, 这个函数接受一个参数作为随机序列的种子,我们用time(0)即系统时间作为种子,保证随机数是真随机而不是伪随机。先构造一个URandGen的对象urg,然后调用urg(),这个调用乍一看好像是函数调用,而实际上它是一个函数对象。
C++标准库为我们提供了一系列函数对象,可供我们使用,使用之前需包含头文件
,即#include
其中包含了诸如less,plus等很实用的操作,可以与transform模板搭配使用,达到事半功倍的效果。举个例子,定义两组vector,把这两组的vector的元素相加,得到另一个vector,代码如下
-
int arrayInput[] = {1, 3, 5, 7, 9,
-
10, 11, 12, 13, 20};
-
vector<int> input1(&arrayInput[0], &arrayInput[5]);
-
vector<int> input2(&arrayInput[5], &arrayInput[10]);
-
vector<int> output(5);
-
transform(input1.begin(), input1.end(),
-
input2.begin(), output.begin(), plus<int>());
-
for (vector<int>::iterator iter = output.begin();
-
iter != output.end();
-
iter++) {
-
cout << *iter << endl;
-
}
该程序把1,3,5,7,9和10,11,12,13,20两组数列加在一起,使用了transform和plus进行了核心操作,输出为
11
14
17
20
29
阅读(1600) | 评论(1) | 转发(0) |