函数符

【1】函数符定义

函数对象,也叫函数符(functor)。即函数符其实是对函数对象的一种别称。

函数符(函数对象)是指可以类似函数方式与()结合使用的任意对象。

那么,很显然,函数符包括函数名、函数指针的对象和重载了()运算符的类对象(即定义了函数operator()()的类)。

【2】函数符种类

(1)函数名

示例如下:

 1 int add(int a, int b)
 2 {
 3     return (a + b);
 4 }
 5 
 6 int main()
 7 {
 8     int a = 100, b = 200;
 9     int c = add(a, b);  // add,即函数名,为函数符一种范畴
10     return 0;
11 }

(2)函数指针的对象

示例如下:

 1 int add(int a, int b)
 2 {
 3     return (a + b);
 4 }
 5 
 6 int main()
 7 {
 8     typedef int(*funcPtr)(int, int);
 9     funcPtr fpAdd = add;
10 
11     int a = 100, b = 200;
12     int c = fpAdd(a, b);  // fpAdd,即函数指针的对象,为函数符的另一种范畴
13     return 0;
14 }

(3)重载了()运算符的类对象

示例如下:

 1 #include <iostream>
 2 
 3 class Linear
 4 {
 5 
 6 private:
 7     double slope;
 8     double y0;
 9 public:
10     //构造函数
11     Linear(double sl_ = 1, double y_ = 0) :slope(sl_), y0(y_) {}
12     //重载()运算符
13     double operator()(double x)
14     {
15         return (y0 + slope * x);
16     }
17 };
18 
19 int main()
20 {
21     Linear f1;
22     Linear f2(2.5, 10.0);
23 
24     //在此处Linear类的对象f1和f2利用重载的()运算符以函数的方式实现了 y0 +slope*x 功能
25     //因此f1和f2可以成为函数符(或函数对象)的另一种范畴
26     double y1 = f1(12.5);
27     double y2 = f2(0.4);
28 
29     std::cout << "y1: " << y1 << std::endl; // 0 + 12.5 * 1 = 12.5
30     std::cout << "y2: " << y2 << std::endl; // 10.0 + 2.5 * 0.4 = 11
31 
32     return 0;
33 }

【3】类函数符作为函数适配器

假设已经有一个接受两个参数的模板函数,则可以使用类将它转换为单个参数的函数对象。

如下示例:

 1 #include <iostream>
 2 #include <list>
 3 #include <algorithm>
 4 
 5 template <class T>
 6 bool tooBig(const T& va1, const T& lim)
 7 {
 8     return va1 > lim;
 9 }
10 
11 template <class T>
12 class TooBig
13 {
14 public:
15     TooBig(const T & t) : cutoff(t) { }
16     bool operator() (const T & v)
17     {
18         return tooBig<T>(v, cutoff);
19     }
20 private:
21     T cutoff;
22 };
23 
24 void coutint(const int& n)
25 {
26     std::cout << n << " ";
27 }
28 
29 int main()
30 {
31     using std::list;
32     using std::cout;
33     using std::endl;
34 
35     cout << "Original lists....\n";
36     list<int> yadayada = { 50, 100, 90, 180, 60, 210, 415, 88, 188, 201 };
37     list<int> etcetera{ 50, 100, 90, 180, 60, 210, 415, 88, 188, 201 };
38     cout << endl;
39 
40     cout << "Before remove print list yadayada:\n";
41     std::for_each(yadayada.begin(), yadayada.end(), coutint);
42     cout << endl;
43 
44     cout << "Before remove print list etcetera:\n";
45     std::for_each(etcetera.begin(), etcetera.end(), coutint);
46     cout << endl << endl;
47 
48     cout << "Remove list yadayada more than 100:\n";
49     TooBig<int> f100(100);
50     yadayada.remove_if(f100);    // use a named function object
51 
52     cout << "Remove list etcetera more than 200:\n";
53     etcetera.remove_if(TooBig<int>(200));  // construct a function object
54 
55     cout << endl;
56     cout << "After remove print list yadayada:\n";
57     std::for_each(yadayada.begin(), yadayada.end(), coutint);
58     cout << endl;
59 
60     cout << "After remove print list etcetera:\n";
61     std::for_each(etcetera.begin(), etcetera.end(), coutint);
62     cout << endl;
63 
64     system("pause");
65 }
66 
67 /*
68 Original lists....
69 
70 Before remove print list yadayada:
71 50 100 90 180 60 210 415 88 188 201
72 Before remove print list etcetera:
73 50 100 90 180 60 210 415 88 188 201
74 
75 Remove list yadayada more than 100:
76 Remove list etcetera more than 200:
77 
78 After remove print list yadayada:
79 50 100 90 60 88
80 After remove print list etcetera:
81 50 100 90 180 60 88 188
82 请按任意键继续. . .
83 */

good good study, day day up.
顺序 选择 循环 总结

posted @ 2020-04-05 14:28  kaizenly  阅读(465)  评论(0编辑  收藏  举报
打赏