现在的位置: 首页 > 综合 > 正文

第六章 通用算法

2017年12月07日 ⁄ 综合 ⁄ 共 3346字 ⁄ 字号 评论关闭

函数对象

函数对象是重载了operator()的类的一个实例,operator()是函数调用运算符。这个运算符允许用函数调用语法并使用对象。如同其他对象一样,可以通过该对象的构造函数来初始化它。

//: C06:GreaterThanN.cpp
#include <iostream>
using namespace std;
 
class gt_n {
  int value;
public:
  gt_n(int val) : value(val) {}
  bool operator()(int n) { return n > value; }
};
 
int main() {
  gt_n f(4);
  cout << f(3) << endl;  // Prints 0 (for false)
  cout << f(5) << endl;  // Prints 1 (for true)
} ///:~
当创建函数对象f时,传递作为比较对照的固定值(4).编译器像下面的函数调用一样计算表达式f(3);
f.operator()(3);
函数对象的分类:
根据operator()使用参数的个数分别为零个,一个或两个的情况进行。
发生器(Generator):一种没有参数且返回一个任意类型值的函数对象。
一元函数(Unary Function):一种只有一个任意类型的参数,且返回一个可能不同类型(比如可能是void)值的函数对象。
二元函数(Binary Function):一种有两个任意类型的(可能是不同类型)参数,且返回一个任意类型(包括void)值的函数对象。
一元判定函数(Unary Predicate):返回bool型值的一元函数。
二元判定函数(Binary Predicate):返回bool型值的二元函数。

自动创建函数对象

例用<functional>定义的大量有用的通用函数对象,在大多数情况下,无需编写任何函数就可以构造出复杂的判定函数。可以用函数对象适配器(function object adaptor)来获得一个简单的函数对象,并且调整它们用来与操作链中的其他函数对象配合。

以下为一个如何利用函数对象适配器来自动创建适当的函数对象:

 

//: C06:CopyIntsToFile.cpp
// Uses an output file stream iterator.
#include <algorithm>
#include <cstddef>
#include <fstream>
#include <iterator>
using namespace std;
 
bool gt15(int x) { return 15 < x; }
 
int main() {
  int a[] = { 10, 20, 30 };
  const size_t SIZE = sizeof a / sizeof a[0];
  ofstream outf("ints.out");
  remove_copy_if(a, a + SIZE,
                 ostream_iterator<int>(outf, "/n"), gt15);
} ///:~

以下的程序没用前面用户自己定义的判定函数gt15(),却产生了相同的结果。函数对象适配器bind2nd()是一个模板函数,它创建一个binder2nd类型的函数对象。仅存储和传递两个参数给bind2nd(),其中第1个参数必须是一个二元函数或函数对象(即带有两个参数的可以被调用的任意对象)。binder2nd中的operator()函数,它本身是一个一元函数,该函数调用存储的二元函数,并传递引入的参数及其存储的固定值。

//: C06:CopyInts4.cpp
// Uses a standard function object and adaptor.
#include <algorithm>
#include <cstddef>
#include <functional>
#include <iostream>
#include <iterator>
using namespace std;
 
int main() {
  int a[] = { 10, 20, 30 };
  const size_t SIZE = sizeof a / sizeof a[0];
  remove_copy_if(a, a + SIZE,
                 ostream_iterator<int>(cout, "/n"),
                 bind2nd(greater<int>(), 15));
} ///:~

抱歉!评论已关闭.