문제

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?

도움이 되었습니까?

해결책

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.

다른 팁

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top