函数对象的好处

The benefit of function objects?

本文关键字:对象 函数      更新时间:2023-10-16

我知道STL中使用的函数对象只是简单的对象,我们可以像函数一样操作它。我可以说函数和函数对象的工作原理是一样的。如果这是真的,那么为什么我们应该使用函数对象而不是函数呢?

这样做的主要好处是对函数对象(函子)的调用通常是可内联的,而对函数指针的调用通常不是(主要的例子是比较C的qsort和c++的std::sort)。对于不重要的对象/比较器,c++应该会降低C的排序性能。

还有其他好处,例如,您可以在函子中绑定或存储状态,这是原始函数无法做到的。

编辑很抱歉没有直接参考,但斯科特·迈耶斯声称在某些情况下改善了670%:qsort与std::sort的性能?

编辑2 表演提示是这样的:

函数指针形参禁止内联的事实解释了长期使用C语言的程序员很难相信:c++的sort实际上总是让C的qsort尴尬速度。当然,c++有函数和类模板来实例化和看起来很滑稽的operator()函数来调用,而C使一个简单的函数调用,但是所有c++的"开销"都在调用过程中被吸收编译。在运行时,sort对其比较进行内联调用函数(假设比较函数已内联声明)它的主体在编译期间可用,而qsort调用它的通过指针比较函数。最终的结果是运行得更快。在我对一百万个双精度向量的测试中,它上升了快670%,但不要相信我的话,你自己试试。这是当比较函数对象和实际函数时,很容易验证作为算法参数,有一个抽象的好处。

-Scott Meyers "Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library" - Item 46

函数对象相对于函数对象的好处是它可以保存状态(来自wikipedia):

#include <iostream>
#include <iterator>
#include <algorithm>
class CountFrom {
private:
  int &count;
public:
  CountFrom(int &n) : count(n) {}
  int operator()() { return count++; }
};
int main() {
  int state(10);
  std::generate_n(std::ostream_iterator<int>(std::cout, "n"), 11, CountFrom(state));
  return 0;
}

普通函数不能像函数对象那样保存状态。如果我没记错的话,这是解决没有lambda和闭包的方法(在c++ 11维基百科章节之前)…

我认为函子最好的地方是它们可以在内部存储信息。在没有std::bind的日子里,人们必须编写大量的一元比较函数,以便将其传递给remove_if等特定例程。

参见http://cs.stmarys.ca/~porter/csc/ref/stl/function_objects.html.

STL使用函数对象(functors)作为对容器进行排序/搜索的回调。函函数是模板,因此更容易作为类实现。试着用函数指针说greater<T>…考虑到STL中的容器也是模板