功能对象的好处?

时间:2013-05-04 01:52:37

标签: c++ function object stl

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

4 个答案:

答案 0 :(得分:6)

主要的好处是对函数对象(仿函数)的调用通常是可内联的,而对函数指针的调用通常不是(例如,将C的qsort与C ++的std::sort进行比较)。对于非平凡的对象/比较器,C ++应该杀死C的排序性能。

还有其他好处,例如,您可以在仿函数中绑定或存储状态,使用该函数不能执行原始函数。

修改 道歉没有直接参考,但Scott Meyers在某些情况下声称改善了670%: Performance of qsort vs std::sort?

编辑2 表演笔记的内容如下:

  

函数指针参数禁止内联的事实解释了一个问题   观察到长期的C程序员经常难以置信:   C ++的排序实际上总是让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

答案 1 :(得分:2)

函数对象对函数的好处是它可以保存状态(来自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;
}

常规函数不能像函数对象那样保持状态。如果我没记错的话,这就是绕过没有lambdas和闭包的方法(在C ++ 11之前wikipedia section)......

答案 2 :(得分:1)

我认为关于仿函数的最好的事情是它们可以在内部存储信息。回到没有std::bind的那些日子里,人们必须编写许多一元比较函数,以便将它传递给某些例程remove_if

答案 3 :(得分:0)

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

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