第六章 通用算法

函数对象

函数对象是重载了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型值的二元函数。
<style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }</style>

自动创建函数对象

例用<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);
} ///:~
<style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }</style>

以下的程序没用前面用户自己定义的判定函数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));
} ///:~
<style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }</style>

你可能感兴趣的:(html,算法,css,F#,asp)