Why do we need "Functor"? Can't template or function pointer work?
Could anybody give me examples that a functor is better than a template/functor pointer? Thanks
Printable View
Why do we need "Functor"? Can't template or function pointer work?
Could anybody give me examples that a functor is better than a template/functor pointer? Thanks
I think this is a typical case of "there are multiple methods that will solve the same problem" - and which is "best" depends partly on your personal preferences, along with "what exactly you are trying to solve".
In other words we don't HAVE TO HAVE functors - but used correctly, they may help to solve some problems in a simpler way.
--
Mats
A functor can carry parametrized information with it. For instance, this functor:
Example usage:Code:class multiply_by
{
public:
multiply_by(double val_p)
: val(val_p)
{ }
double operator()(double x)
{
return x * val;
}
private:
double val;
};
Let's see you do that without a functor and without passing a second parameter to times_three().Code:multiply_by times_three(3.0);
double x = 15.0;
double result = times_three(x);
Or being able to use the same method to do things instead of having to write a new method for them all the time. Like in this example, where we can sort by a person's name, or do a lot of other things, like, find someone. It might not even matter what kind of person he or she is. Functors encapsulate these types of ideas better than a "real" function because you can control they're lifetime especially. Pay attention in the example where by_name exists only while it is being used.
My output:Code:#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
class Person {
private:
std::string name;
public:
Person( const char * my_name = "John Doe" ) :
name( my_name )
{
}
virtual ~ Person( )
{
}
std::string getName( ) const
{
return name;
}
};
class Student: public Person {
private:
double gpa;
bool present;
public:
Student( const char * my_name = "John Doe", double gpa_in = 3.0, bool attended = true ) :
Person( my_name ), gpa( gpa_in ), present( attended )
{
}
bool isPresent( ) const
{
return present;
}
};
template< class Handle > struct by_name {
bool operator( ) ( const Handle &lst, const Handle &rst ) const
{
return lst.Person::getName() < rst.Person::getName();
}
};
int main( )
{
std::vector< Student > classroom;
classroom.push_back( Student( "Mary Jane", 3.75 ) );
classroom.push_back( Student( "Oliver Warbucks", 2.9, false ) );
classroom.push_back( Student( "Troy Percival", 4.0, false ) );
classroom.push_back( Student( "Donna Mosley", 3.15, true ) );
classroom.push_back( Student( "Gary Gadget" ) );
std::cout << "Roll call!!\n\n";
std::sort( classroom.begin(), classroom.end(), by_name< Student >() );
for( std::vector< Student >::iterator iter = classroom.begin();
iter != classroom.end(); iter++ )
std::cout << iter->getName() << " is " << ( iter->isPresent()? "here\n":"not here\n" );
std::cout << '\n';
std::cout << "John Doe " <<
( std::binary_search( classroom.begin(), classroom.end(), "John Doe", by_name< Student >() )? "is":"is not" )<<
" in the classroom\n";
}
Roll call!!
Donna Mosley is here
Gary Gadget is here
Mary Jane is here
Oliver Warbucks is not here
Troy Percival is not here
John Doe is not in the classroom
Another adavantage of functor objects is that the compiler can inline the functor call much easier than a raw function pointer.
gg