这一章讲的是仿函数(Functor),大陆叫函子(咋听起来那么别扭。。。),需要把第五章的仿函数部分看明白。
- 1.(P124)
仿函数的基础: 行为类似函数,从实现的角度来看,仿函数是一种重载了Operator()的Class 或 Class Template。一般函数指针可视为狭义的仿函数。
函数行为:指可以"使用小括号传递参数,藉以调用某个东西", eg. function(arg1, arg2)。
如果希望对象也可以这样,可以通过重载"()"操作符(operator() ),并给予合适的参数型别:
class X{
public:
// define "function call" operator
return-type operator() (arguements) const;
...
};
现在,就可以把这个对象当做函数调用了"
X tk;
...
tk(arg1, arg2);
上述调用等价于:
tk.operator() (arg1, arg2);
- 2.(P125)
入门级的仿函数程序,可以更清楚的理解神马是仿函数。
#include
#include
#include
#include
#include
using namespace std;
class PrintInt
{
public:
void operator() (int elem) const {
cout << elem << " ";
}
};
int main()
{
vector coll;
for(int i=1; i<=9; ++i)
coll.push_back(i);
for_each(coll.begin(), coll.end(), PrintInt()); // ———- ①
cout << endl;
return 0;
}
- 3.(P128)
仿函数的优点: ①.仿函数可以拥有自己的状态(state),所以比一般函数更灵巧。 ②.仿函数都有其型别。 ③.执行速度上,仿函数比函数指针更快。
在编译期间像函数传递参数,可以使用模板,但是模板必须是常量。这时,可以选择用仿函数。 具体对比P(128)~P(129)的两个例子。
- 4.(P294)
对于仿函数的个人理解: 仿函数就是一个类,而使用仿函数使其模拟函数行为就是利用类对象的()操作符,即调用Class()。 要使用仿函数的operator(),可以选择建一个临时对象或者普通的类对象。 建临时对象如上述第二点中的代码中,注意为①的那一行。 PrintInt()是建立一个临时仿函数对象。 当然,也可以选择:
PrintInt prin();
for_each(coll.begin(), coll.end(), prin); //这样就容易理解一些。
关于更多对仿函数对象使用的讨论,可以看我在CSDN上的求助帖: http://topic.csdn.net/u/20110129/00/1a9db6ac-a65e-460b-aaaa-554e2bdf6450.html?seed=1711992303&r=71476802
- 5.(P298)
将仿函数以passed by reference方式传递。 这样就可以改变仿函数的状态。
// print.h
#include
using namespace std;
template
inline void PRINT_ELEMENTS(const T& coll, const char* optcstr="")
{
typename T::const_iterator pos;
cout << optcstr;
for(pos=coll.begin(); pos!=coll.end(); ++pos)
cout << *pos << ‘ ‘;
cout << endl;
}
// main.cpp
#include
#include
#include
#include
#include
#include
#include "print.h"
using namespace std;
class IntSequence{
private:
int value;
public:
IntSequence (int initialValue)
: value(initialValue) {}
int operator() () {
return value++;
}
};
int main()
{
//freopen("out.txt", "w", stdout);
list coll;
IntSequence seq(1);
generate_n >,
int, IntSequence&>(back_inserter(coll),
4,
seq);
PRINT_ELEMENTS(coll);
generate_n(back_inserter(coll),
4,
IntSequence(42));
PRINT_ELEMENTS(coll);
generate_n(back_inserter(coll),
4,
seq);
PRINT_ELEMENTS(coll);
generate_n(back_inserter(coll),
4,
seq);
PRINT_ELEMENTS(coll);
}
输出结果: 1 2 3 4 1 2 3 4 42 43 44 45 1 2 3 4 42 43 44 45 1 2 3 4 1 2 3 4 42 43 44 45 1 2 3 4 1 2 3 4
- 6.(P305)
预定义的仿函数 要使用这些仿函数,必须包含头文件
#include