Showing posts with label Functors. Show all posts
Showing posts with label Functors. Show all posts

Tuesday, 22 February 2011

A generic sort program with 'functors' and 'templates'

Picked up this question from here and made a program out of it. It may be a good idea to quickly brush functors and templates if required.

The program sorts the input Vector provided regardless of the type.




//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

using namespace
std;

class
Int
{

public
:
Int() {x_ = 0;}
Int(const int &x) {x_ = x;}
int
getID (void) {return x_;}
int
x_;
};


class
Str
{

public
:
Str() {x_ = "";}
Str(const string &x) {x_ = x;}
string getID (void) {return x_;}
string x_;
};


template
<typename Object> class Comparator {
public
:
bool
operator()(const Object &o1, const Object &o2) const
{

return
(const_cast<Object&>(o1).getID() < const_cast<Object&>(o2).getID());
}


bool
operator()(const Object *o1, const Object *o2) const {
return
(o1->getID() < o2->getID());
}
};


template
<typename VecObject> void Display(VecObject v)
{

VecObject::iterator it;
for
(it = v.begin(); it != v.end(); ++it)
{

cout<<it->getID()<<", ";
}

cout<<endl;
}


int
main()
{

vector<Int> objects1;
objects1.push_back(Int(3));
objects1.push_back(Int());
objects1.push_back(Int(77));

//print the output
cout<<"objects1 before sort = ";
Display(objects1);
std::sort(objects1.begin(), objects1.end(), Comparator<Int> ());
cout<<"objects1 after sort = ";
Display(objects1);

std::vector<Str> objects2;
objects2.push_back(Str("Hello Hello"));
objects2.push_back(Str("apple?"));
objects2.push_back(Str());
objects2.push_back(Str("1 Jump"));

//print the output
cout<<"objects2 before sort = ";
Display(objects2);
std::sort(objects2.begin(), objects2.end(), Comparator<Str> ());
cout<<"objects2 after sort = ";
Display(objects2);

return
0;
}




The output is as follows:

Wednesday, 7 April 2010

Example of 'functors'

What are 'functors?'

Depending on what you prefer to read, there are many definitions and explanations of Functors.

From the function pointer tutorial:

Functors are functions with a state. In C++ you can realize them as a class with one or more private members to store the state and with an overloaded operator () to execute the function. Functors can encapsulate C and C++ function pointers employing the concepts templates and polymorphism. You can build up a list of pointers to member functions of arbitrary classes and call them all through the same interface without bothering about their class or the need of a pointer to an instance. All the functions just have got to have the same return-type and calling parameters. Sometimes functors are also known as closures. You can also use functors to implement callbacks.

From StackOverflow:
  • A functor is pretty much just a class which defines the operator(). That makes it "look like" a function.
  • Another advantage to a functor over a pointer to a function is that the call can be inlined in more cases.
  • You can use boost::function, to create functors from functions and methods
Here is a simple example of functors that I have created using mishmash from various places:



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Program to demonstrate the use of functors

#include<iostream>

using namespace
std;

class
someClass
{

public
:
someClass(int x) : someVariable(x) {}
int
operator()(int y) {return (someVariable + y);}
int
internalStateValue(){return someVariable;}

private
:
int
someVariable;
};


int
main()
{

someClass class1(50);
someClass class2(75);

cout<<"Class1 state variable value is : "<<class1.internalStateValue()<<endl;
cout<<"Class2 state variable value is : "<<class2.internalStateValue()<<endl;

int
test1 = class1(22);
cout<<"Test 1 value is : "<< test1<<endl;
int
test2 = class2(22);
cout<<"Test 2 value is : "<< test2<<endl;

cout<<"Class1 final state variable value is : "<<class1.internalStateValue()<<endl;
cout<<"Class2 final state variable value is : "<<class2.internalStateValue()<<endl;

return
0;
}





The output is as follows: