函数对象的好处
The benefit of function objects?
我知道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中的容器也是模板
- 如何创建对象函数指针C++映射?
- 为什么我可以改变常量对象中的成员变量,这是返回常量对象函数的结果?
- 如何将对象函数的实例传递给另一个函数
- 调用模板函数的问题"No matching function for call"参数:迭代器、对象函数
- makefile对我的名称空间对象/函数/构造函数的不确定引用
- 将对象函数转换为函数指针
- 非对象函数/类函数C++
- 线程对象函数 C++
- C 将成员对象函数分配给类成员功能
- 使用基本指针调用派生对象函数
- 可以(通过编译器)使用多少个线程来初始化全局对象(函数main之前)
- C++类对象函数
- 对对象::函数的未定义引用
- 无法弄清楚将多个对象函数作为单独的线程调用的语法
- 在提升作用域出口中调用对象函数
- 使用基指针来使用派生对象函数
- 在for_each lambda 中调用对象函数
- C++:: 模板函数 - 从对象函数获取对象的地址
- Qt5 未解析的外部静态元对象函数
- 通过变量使用对象和对象函数