Question

I have a worker thread, which holds a list of 'Thread Actions', and works through them as an when.

template <class T> class ThreadAction
{
public:

  typedef void (T::*action)();

  ThreadAction(T* t, action f) :
    func(f),obj(t) {}
  void operator()() { (obj->*func)(); }

  void (T::*func)();
  T* obj;

};

It's normally called like this

myActionThread->addAction(
    new ThreadAction<TheirClass>(this, &TheirClass::enable)
);

Which worked fine until

 void TheirClass::enable()

was changed to

 bool TheirClass::enable()

Sadly we can't change it back again because other stuff needs the new format, (and overloads can't differ by return type alone).

I did try

myActionThread->addAction( 
    new ThreadAction<TheirClass>(this, 
        reinterpret_cast<void(TheirClass::*)>(&TheirClass::enable)
    )
);

Which appears to work just fine, but I'm not certain that reinterpreting a function pointer like this is 'defined' behaviour, can somebody please advise?

Was it helpful?

Solution

This is definitely not supported behavior, and can potentially cause your program to crash.

Basically, you need to make a wrapper for TheirClass::enable() that will have the proper return type. A simple one-liner will suffice:

public:
    void enableWrapper() { enable(); };

Then call:

myActionThread->addAction(
    new ThreadAction<TheirClass>(this, &TheirClass::enableWrapper)
);

If you can't modify TheirClass directly, then create a simple subclass or helper class that implements the wrapper.

OTHER TIPS

Err, from what I've understood, you're casting from a method that returns a bool to a method that returns void ?

This may be dangerous, depending on the calling/returning convention in use. You might forget to pop the return value - or override the value of a register with the return value.

Not a good idea. Consider adding an additional template parameter for return type:

template <class T, typename RetType> class ThreadAction
{
public:
 typedef RetType (T::*action)();
 ThreadAction(T* t, action f) :
   func(f),obj(t) {}

 RetType operator()() { return (obj->*func)(); }
 RetType (T::*func)();
 T* obj;
};

This is an application of return void.

I generally find that when the question is of the form "Is _______ a good idea?" the answer is almost invariably "NO!"

This is probably true without context.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top