sorting a vector, functors, and std::binary_function

C

Christopher

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". 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()?

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...

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?

Thanks!
 
R

red floyd

Christopher said:
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". 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()?

It can be inlined by std::sort().

Using a function pointer is perfectly legitimate. A functor is
"anything that looks and behaves like a function".
 
M

Matthias Buelow

Christopher said:
What they fail
to tell me is, what is the advantage to wrapping some comparison
function in a class and calling it operator()?

You can't pass a (non-static) member function since the hidden object
pointer isn't typically part of the function's pointer; hence this
mechanism.
I think that's the main reason -- basically a workaround.
 
P

Phil Endecott

Christopher said:
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?

Please consider the code below to be pseudo-code.

// Contrived textbook example with constant state:

struct mul {
const int multiplier;
mul(int multiplier_): multiplier(multiplier_) {}
void operator()(int n) { n *= multiplier; }
};

mul quadruple(4);
mul tripple(3);

vector<int> i = .......;
foreach(i.begin, i.end, quadruple);


// You could imagine non-const state in something like.

struct find_min_max .......
log_min_max minmax;
foreach(i.begin(), i.end(), minmax);


// A real example that I use is:

charset_converter utf8_to_8859_1("utf8","iso8859-1");

while (!end-of-input) {
s += utf8_to_8859_1(next_bit);
}

Here the functor state is any partial multi-byte characters.



Regards,

Phil.
 
J

James Kanze

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Functors 2
OpenMP and functors 1
std::binary_function 9
Iterators and functors 4
functors 2
Sorting Structure Data within Vector 1
static_cast and std::vector 9
Advancing Through std::vector 15

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top