Template Method + function objects (comparators)

From: Val (valmont_programming_at_hotmail.com)
Date: 09/28/04


Date: Tue, 28 Sep 2004 23:26:52 +0200

Assume a member-function...

//Pass the correct Template Method class to IFieldOrder* .
void PhoneBookEngine::SortAndSearch( const vector<Person>& a, const string& field, IFieldOrder* fo )
{

 ///sort(PBk.getPhoneBook().begin(), PBk.getPhoneBook().end(), ??? );

   int low = 0, high = a.size() - 1;
   while( low <= high )
   {
      int mid = ( low + high ) / 2;
      if( fo->smaller(a[ mid ], field) )
            low = mid + 1;
      else if( fo->bigger(a[ mid ], field) )
            high = mid - 1;
      else
      { IdxRecord = mid; delete fo; return; } //Found.
   }
   { delete fo; return; } //Not found.
}

...and the Template Method....

/*** IFieldOrder.h ***/

#ifndef IFIELDORDER_H
#define IFIELDORDER_H

#include "Person.h"
#include <string>

using namespace std;

class IFieldOrder
{
public:
   virtual bool Less(const Person& a, const Person& b)=0;
 virtual bool smaller(const Person& lhs, const string& rhs)=0;
 virtual bool bigger(const Person& lhs, const string& rhs)=0;
};

#endif //IFIELDORDER_H

/*** FirstNameOrder.h ***/

#ifndef FIRSTNAMEORDER_H
#define FIRSTNAMEORDER_H

#include "IFieldOrder.h"

class FirstNameOrder : public IFieldOrder
{
public:
   FirstNameOrder() {}
   inline bool smaller(const Person& lhs, const string& rhs) const
   { return lhs.fname < rhs; }
 inline bool bigger(const Person& lhs, const string& rhs) const
 { return lhs.fname > rhs; }
};

#endif //FIRSTNAMEORDER_H

...etcetera.

The problem child is " sort(PBk.getPhoneBook().begin(), PBk.getPhoneBook().end(), ??? ); " .
How can I exploit the fact that PhoneBookEngine::SortAndSearch() knows about the correct (Template)Method to pass a
comparator to std::sort.

Normally something like this would do:

class LessFirstName
{
    bool operator() (const Person& a, const Person& b)
    { return a.fname < b.fname }
};

But I have three classes derrived from IFieldOrder. So I can sort and search objects using one of their properties as a
key. Searching is easy. Just use the Template Method. But How can I sort, using the existing template method classes as
a guide. I don't care how the comparators are created by the three classes. In the end I am *hoping* for something like
(see std::sort() ) :

 //Later I'll decide how to manage IFieldOrder. Most likely work for the constructor. For now this though.
void PhoneBookEngine::SortAndSearch( const vector<Person>& a, const string& field, IFieldOrder* fo )
{
 sort(PBk.getPhoneBook().begin(), PBk.getPhoneBook().end(), fo->cmp() ); // <====Right here guys :)

   int low = 0, high = a.size() - 1;
   while( low <= high )
   {
      int mid = ( low + high ) / 2;
      if( fo->smaller(a[ mid ], field) )
            low = mid + 1;
      else if( fo->bigger(a[ mid ], field) )
            high = mid - 1;
      else
      { IdxRecord = mid; delete fo; return; } //Found.
   }
   { delete fo; return; } //Not found.
}

That's it basically.