I have known that the function objects used in STL is just simple object that we can operator it like a function. That I can say the works of function and function objects is the same. If it's true, then why we should used function object rather than function?
4 Answers
The primary benefit is that calls to function objects (functors) are generally inlineable, where as calls to function pointers are generally not (prime example is comparing C's qsort
to C++'s std::sort
). For non-trivial objects/comparators, C++ should kill C's performance for sorting.
There are other benefits, for example you could possibly bind or store state in a functor, with which a raw function you cannot do.
Edit Apologies for no direct reference, but Scott Meyers claims 670% improvement under certain circumstances: Performance of qsort vs std::sort?
Edit 2 The passage with the performance note is this:
The fact that function pointer parameters inhibit inlining explains an observation that long-time C programmers often find hard to believe: C++’s sort virtually always embarrasses C’s qsort when it comes to speed. Sure, C++ has function and class templates to instantiate and funny-looking operator() functions to invoke while C makes a simple function call, but all that C++ “overhead” is absorbed during compilation. At runtime, sort makes inline calls to its comparison function (assuming the comparison function has been declared inline and its body is available during compilation) while qsort calls its comparison function through a pointer. The end result is that sort runs faster. In my tests on a vector of a million doubles, it ran up to 670% faster, but don’t take my word for it, try it yourself. It’s easy to verify that when comparing function objects and real functions as algorithm parameters, there’s an abstraction bonus.
-Scott Meyers "Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library" - Item 46

- 1
- 1

- 4,540
- 25
- 38
-
1@PhilipDahnen: It's mostly theoretical I think, function pointers you can't know where it points at compile-time and thus can't be inlined except for trivial cases. functors have the function embedded in the type and so are trivially inlinable in all cases. – Mooing Duck May 04 '13 at 02:10
-
AS @PhilipDahnen states, it is mostly theoretical from a hypothetical stance. In practice, you should look at the generated assembly for your case, to be sure. If you look at the generated assembly in an optimized build, it should be readily apparent. Note: this will likely only make a difference if the implementation of the functor in question is inlinable. – Nathan Ernst May 04 '13 at 02:16
-
There are cases when the compiler will not inline a function: such as debug builds. Alternately, some compilers will not inline some functions, even marked as inline, due to size, complexity, etc. `inline` is not a command, it is a hint to the compiler/linker. – Nathan Ernst May 04 '13 at 02:19
The benefit of a function object over a function is that it can hold state (from 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;
}
A regular function cannot hold state like a function object. If I remember correctly it was the way of getting around not having lambdas and closures (before C++11 wikipedia section)...

- 777
- 4
- 12
-
Yes, I understand the first sentence. but the next I can't understand. Can you expland it for me? Thanks. – legend May 07 '13 at 10:09
-
Lambdas are nameless functions that are declared inline. C++11 added lambdas, and one of the features is it can "capture" variables and use them in the function. Wikipedia has an article on [closures](http://en.wikipedia.org/wiki/Closure_%28computer_science%29) – scaryrawr May 10 '13 at 20:57
I think that the best thing about functors are that they can store information internally. Back in those days without std::bind
, one would have to write lots of unary comparison functions so that it can be passed to certain routines like remove_if
.

- 2,080
- 17
- 20
See http://cs.stmarys.ca/~porter/csc/ref/stl/function_objects.html.
STL uses function objects (functors) as a callback for sorting/searching containers.
Functors are templates and thus easier to implement as classes. Try saying greater<T>
with a function pointer... considering that containers in STL are templates, too.

- 271
- 1
- 15
-
k, [wrote `greater
` with a function pointer](http://coliru.stacked-crooked.com/view?id=2f17777430c1b7290e0d11e906ca5029-50d9cfc8a1d350e7409e81e87c2653ba). Now what? – Mooing Duck May 04 '13 at 02:09 -
@MooingDuck: yeah, your point! Yet I was talking about the pointer type, which is also not such a big deal, I see... – Philip May 04 '13 at 02:13
-
The type of `greater
` in my example is `bool (*)(const int&, const int&)`, but yeah, other than that your answer was good. – Mooing Duck May 04 '13 at 02:19 -
@MooingDuck: Is it somehow possible to declare a template function pointer in global scope? Like erroneous `template
typedef bool (*cmp)(const T&, const T&);`? – Philip May 04 '13 at 02:29 -
A template 'template
cmp' is NOT a function, so you cant have a pointer to it. But a instantiatiin (not the right word, forgot the right one) like 'greater – Mooing Duck May 04 '13 at 09:37' is a function and can thus have a pointer. In C++11 you can use 'using' to alias a template though.