On Nov 28, 6:56 pm, Christopher <cp...@austin.rr.comwrote:
I used to just use a plain old function pointer is a call to
std::sort.
My colleagues are telling me that I need to use a "functor".
Don't believe them.
Ok, I google and see that a functor is a class with a public
method, operator () that does the comparison. Fine, no
problem. What they fail to tell me is, what is the advantage
to wrapping some comparison function in a class and calling it
operator()?
The use of a functor means that there is a separate
instantiation of std::sort for each function (since each functor
has a different type), and that the actual function is known in
the instantiation of std::sort. This can (in some cases) result
in slightly faster code, because the compiler can inline the
comparison. It can (in certain other cases) result in code
bloat, because the compiler must generate a separate
instantiation of the std::sort function template for each
different function. 99% of the time, it doesn't matter.
I also read that "functors" are supposed to be a class that wraps a
function pointer and additionally holds a state. What kind of state,
what is the typical scenario? I don't see any state data in any of my
colleagues code...
First, it doesn't wrap a function pointer; it has a member
function which does the job. Secondly, it's very, very rare for
a binary predicate to contain state. Other functors often do,
however: the predicate for std::find_if may (in fact, usually
will) contain the key you're looking for. And even binary
precidates can contain state; if you want to do a case
insensitive comparison of strings, for example, you might embed
a pointer to the desired std::ctype facet in the predicate, for
example.
I also googled for examples on doing a sort upon a vector
using this concept of a functor to get the syntax correct. I
notice that one example derives his functor from
std::binary_function. Google binary_function and see that it
is described as "a base class for a functor", well that
doesn't tell me much. Why do some of the examples I've found
derive from std::binary_function while others do not?
No real reason. When you start composing several functors, it
becomes necessary that the functors being composed contain
typedefs indicating their argument and return value types. The
class std::binary_function provides these, but you can also
provide them manually. And they're only used when you start
composing, using things like std::bind2nd. Which means that if
you're writing a local functor, which can't be seen outside your
source, there's no real point in them at all.
--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34