views:

60

answers:

2

I have a SpecialisedRedBlackTree class that is templated.

My Month class is not.

In my Month class I have a private member which is an instance of SpecialisedRedBlackTree:

SpecialisedRedBlackTree<Day> m_windSpeedTree;

As you can see it will take the Day class/object (please correct me on any terms I get wrong).

In my Month class, I have a method passing a method function pointer to this method:

bool Month::CompareWindSpeed(Day a, Day b) {
return ( a.GetData(WIND_SPEED_CODE) < b.GetData(WIND_SPEED_CODE)? true : false);
}

bool (Month::*myFuncPtr)(Day, Day);
myFuncPtr = &Month::CompareWindSpeed;
m_windSpeedTree.Insert(dayReading, myFuncPtr);

But because I am passing a bool (Day, Day) pointer to a templated class expecting bool (T, T)

T being part of this .... template

Error 1 error C2664: 'SpecialisedRedBlackTree<T>::Insert' : cannot convert parameter 2 from 'bool (__thiscall Month::* )(Day,Day)' to 'bool (__cdecl *)(T,T)'

Any advice?

A: 

A function of an object is not the same as a normal function in regards to function pointers. You need to store a reference to the object it self and also the function pointer to be able to call it.

For Example a class to store the functior and object pointer:

template <class TObj, typename TArg>
class ObjDelegate
{
public:
 typedef void (TObj::*TFunct)(TArg&);

 ObjDelegate(TObj* t, TFunct f)
 {
  m_pObj = t;
  m_pFunct = f;
 }

 virtual void operator()(TArg& a)
 {
  if (m_pObj && m_pFunct)
  {
   (*m_pObj.*m_pFunct)(a);
  }
 }

 TFunct m_pFunct;   // pointer to member function
 TObj* m_pObj;     // pointer to object
};

To use it you would do this:

ObjDelegate<MyClass, MyParam> objDel = new ObjDelegate(this, MyClass::MyMethod);

To trigger the function call:

MyParam myParamInstance;
objDel(myParamInstance);
Lodle
You *cannot* treat it as normal function in a context where an ordinary function pointer is expected. In fact, C++ language provides no means to transform a member function pointer into a freestanding (ordinary) function pointer. It is simply impossible, without using platform-specific hacks. In other words, until the tree interface is changed to accept functors, your solution will not really solve anything.
AndreyT
Well instead of using a functor he could change to accept a ObjDelegate.
Lodle
+2  A: 

The problem at this point is not that the class is templated, but that you are passing a member-function where a non-member function is expected.

You could:

  • make CompareWindSpeed() a free function or a static member function
  • let Insert() take a member function pointer and an instance pointer
  • use tr1::function or boost::function or similar wrappers instead of function pointers
Georg Fritzsche