当前位置:嗨网首页>书籍在线阅读

26-函数对象

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

16.5 函数对象

很多STL算法都使用函数对象——也叫函数符(functor)。函数符是可以以函数方式与()结合使用的任意对象。这包括函数名、指向函数的指针和重载了()运算符的类对象(即定义了函数operator()()的类)。例如,可以像这样定义一个类:

class Linear
{
private:
    double slope;
    double y0;
public:
    Linear(double sl_ = 1, double y_ = 0)
        : slope(sl_), y0(y_) {}
    double operator()(double x) {return y0 + slope * x; }
};

这样,重载的()运算符将使得能够像函数那样使用Linear对象:

Linear f1;
Linear f2(2.5, 10.0);
double y1 = f1(12.5); // right-hand side is f1.operator()(12.5)
double y2 = f2(0.4);

其中y1将使用表达式0 + 1 12.5来计算,y2将使用表达式10.0 + 2.5 0.4来计算。在表达式y0 + slope * x中,y0和slope的值来自对象的构造函数,而x的值来自operator() ()的参数。

还记得函数for_each吗?它将指定的函数用于区间中的每个成员:

for_each(books.begin(), books.end(), ShowReview);

通常,第3个参数可以是常规函数,也可以是函数符。实际上,这提出了一个问题:如何声明第3个参数呢?不能把它声明为函数指针,因为函数指针指定了参数类型。由于容器可以包含任意类型,所以预先无法知道应使用哪种参数类型。STL通过使用模板解决了这个问题。for_each的原型看上去就像这样:

template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f);

ShowReview()的原型如下:

void ShowReview(const Review &);

这样,标识符ShowReview的类型将为void(*)(const Review &),这也是赋给模板参数Function的类型。对于不同的函数调用,Function参数可以表示具有重载的()运算符的类类型。最终,for_each()代码将具有一个使用f()的表达式。在ShowReview()示例中,f是指向函数的指针,而f()调用该函数。如果最后的for_each()参数是一个对象,则f()将是调用其重载的()运算符的对象。