C++仿函数

2

C++仿函数

  重载函数调用操作符的类,其对象称为函数对象,因为使用重载的()时,其行为类似于函数的调用,因此也称之为仿函数。但是仿函数是一个类,并不是一个函数

仿函数

仿函数是一个类,其特点是:

  • 函数对象在使用时可以像普通函数那样调用,可以有返回值
  • 函数对象超出普通函数的概念,函数对象有自己的状态,可以设置一个成员属性,记录函数调用的次数,时间等等
  • 函数对象可以作为参数进行传递
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include<iostream>
using namespace std;

// 这里定义一个仿函数
class KxPlusb {
public:
int operator()(int k, int x, int b) {
cout << "这里调用了KxPlusb这个类的运算符重载函数" << endl;
return k * x + b;
}
};

// 这里定义一个普通函数
int kxPlusb(int k, int x, int b) {
cout << "这里调用了kxPlusb这个普通函数" << endl;
return k * x + b;
}

int main() {

// 创建一个仿函数的对象
KxPlusb line;
// 调用仿函数
cout << "1 * 2 + 3 = " << line(1, 2, 3) << endl;
// 调用普通函数
cout << "1 * 2 + 3 = " << kxPlusb(1, 2, 3) << endl;

return 0;
}

1

一元谓词

谓词是返回值为布尔类型的仿函数,如果operator()只接收一个参数,那么称之为一元谓词

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

// 定义一个一元谓词,判断参数是否为奇数
class IsOdd {
public:
bool operator()(int val) {
return val % 2;
}
};

int main() {

IsOdd isOdd;
cout << "2是否为奇数:" << isOdd(2) << endl;
cout << "3是否为奇数:" << isOdd(3) << endl;

vector<int> v = { 2,4,5,6,8 };
// 这里使用了后面将要讲到的algorithm中的一些函数
// 谓词的使用主要是用在一些函数中,可以简化我们的代码。
// find_if(_InIt _First, const _InIt _Last, _Pr _Pred)是从迭代器范围中寻找第一个满足条件的数据,并返回迭代器位置。其中第三个参数就是谓词,如果为真则停止,为假则继续寻找。
vector<int>::iterator it = find_if(v.begin(), v.end(), isOdd);

if (it == v.end()) {
cout << "从vector中没有找到奇数" << endl;
}
else {
cout << "从vector中找到了奇数,第一个奇数为:" << *it << endl;
}

return 0;
}

1

二元谓词

如果operator()接收两个参数,那么称之为二元谓词

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

// 定义一个二元谓词,判断a的平方是否小于b的平方
class SquareCmp {
public:
bool operator()(int a, int b) {
return a * a < b * b;
}
};

void printVector(vector<int> v) {
cout << "v:";
for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
cout << *it << " ";
}
cout << endl;
}

int main() {

SquareCmp squareCmp;

cout << "3的平方是否小于4的平方:" << squareCmp(3, 4) << endl;
cout << "-5的平方是否小于4的平方:" << squareCmp(-5, 4) << endl;

vector<int> v = { -5,4,2,-6,8 };
// 这里使用了后面将要讲到的algorithm中的一些函数
// 谓词的使用主要是用在一些函数中,可以简化我们的代码。
// sort(const _RanIt _First, const _RanIt _Last, _Pr _Pred)是对迭代器范围内的元素进行排序。其中第三个参数就是谓词,指定了排序的规则。
sort(v.begin(), v.end(), squareCmp);

printVector(v);

return 0;
}

1

内建算术仿函数

C++提供了6个内建算数仿函数,可以导入functional头文件进行使用

  • plus 加法二元仿函数,
  • minus 减法二元仿函数
  • multiplies 乘法二元仿函数
  • divides 除法二元仿函数
  • modulus 取模二元仿函数
  • negate 取负一元仿函数
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    #include<iostream>
    #include<functional>
    using namespace std;

    int main() {

    plus<int> pl;
    cout << "20 + 10 = " << pl(20, 10) << endl;

    minus<int> mi;
    cout << "20 - 10 = " << mi(20, 10) << endl;

    multiplies<int> mu;
    cout << "20 * 10 = " << mu(20, 10) << endl;

    divides<int> di;
    cout << "20 / 10 = " << di(20, 10) << endl;

    modulus<int> mo;
    cout << "20 % 10 = " << mo(20, 10) << endl;

    negate<int> ne;
    cout << "-10 = " << ne(10) << endl;

    return 0;
    }
    1

内建关系仿函数

C++提供了6个内建关系仿函数,可以导入functional头文件进行使用

  • equal_to 等于二元仿函数,
  • not_equal_to 不等于二元仿函数
  • greater 大于二元仿函数
  • greater_equal 大于等于二元仿函数
  • less 小于二元仿函数
  • less_equal 小于等于二元仿函数
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    #include<iostream>
    #include<functional>
    using namespace std;

    int main() {

    equal_to<int> eq;
    cout << "3是否等于3:" << eq(3, 3) << endl;
    cout << "2是否等于3:" << eq(2, 3) << endl;

    not_equal_to<int> ne;
    cout << "3是否不等于3:" << ne(3, 3) << endl;
    cout << "2是否不等于3:" << ne(2, 3) << endl;

    greater<int> gr;
    cout << "3是否大于3:" << gr(3, 3) << endl;
    cout << "3是否大于2:" << gr(3, 2) << endl;

    greater_equal<int> ge;
    cout << "3是否大于等于3:" << ge(3, 3) << endl;
    cout << "3是否大于等于2:" << ge(3, 2) << endl;

    less<int> ls;
    cout << "2是否小于3:" << ls(2, 3) << endl;
    cout << "3是否小于3:" << ls(3, 3) << endl;

    less_equal<int> le;
    cout << "2是否小于等于3:" << le(2, 3) << endl;
    cout << "3是否小于等于3:" << le(3, 3) << endl;

    return 0;
    }
    1

内建逻辑仿函数

C++提供了3个内建逻辑仿函数,可以导入functional头文件进行使用

  • logical_and 与二元仿函数,
  • logical_or 或二元仿函数
  • logical_not 非一元仿函数
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    #include<iostream>
    #include<functional>
    using namespace std;

    int main() {

    logical_and<bool> la;
    cout << "true && true = " << la(true, true) << endl;
    cout << "false && true = " << la(false, true) << endl;
    cout << "true && false = " << la(true, false) << endl;
    cout << "false && false = " << la(false, false) << endl;

    logical_or<bool> lo;
    cout << "true || true = " << lo(true, true) << endl;
    cout << "false || true = " << lo(false, true) << endl;
    cout << "true || false = " << lo(true, false) << endl;
    cout << "false || false = " << lo(false, false) << endl;

    logical_not<bool> ln;
    cout << "!true = " << ln(true) << endl;
    cout << "!false = " << ln(false) << endl;

    return 0;
    }
    1

C++小结

  仿函数是C++STL算法的基础,在这里我们先掌握基本的仿函数定义,以及C++的一些内建仿函数。在后面我们将要学习一些常用的算法,其中如果想按照自己需要的方式改进标准算法,则需要传入一元谓词或者二元谓词,在这一讲的find_if和sort函数中也有所涉及。

-------------本文结束感谢您的阅读-------------
0%