2

我有一个工作线程,它包含一个“线程操作”列表,并作为时间处理它们。

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;

};

通常是这样称呼的

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

哪个工作得很好,直到

 void TheirClass::enable()

改为

 bool TheirClass::enable()

遗憾的是,我们无法再次将其更改回来,因为其他内容需要新格式(并且重载不能仅因返回类型而异)。

我确实尝试过

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

这似乎工作得很好,但我不确定重新解释这样的函数指针是“定义”的行为,有人可以建议吗?

4

4 回答 4

9

这绝对不是受支持的行为,并且可能会导致您的程序崩溃。

基本上,您需要为其制作一个TheirClass::enable()具有正确返回类型的包装器。一个简单的单行就足够了:

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

然后调用:

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

如果不能TheirClass直接修改,则创建一个简单的子类或帮助类来实现包装器。

于 2009-10-15T15:00:07.523 回答
2

错误,据我了解,您正在从返回 abool的方法转换为返回的方法void

这可能很危险,具体取决于使用的调用/返回约定。您可能忘记弹出返回值 - 或用返回值覆盖寄存器的值。

于 2009-10-15T15:05:09.993 回答
2

不是一个好主意。考虑为返回类型添加一个额外的模板参数:

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;
};

这是return void的一个应用。

于 2009-10-15T15:05:13.020 回答
1

我通常发现,当问题的形式是“________ 是个好主意吗?” 答案几乎总是“不!”

如果没有上下文,这可能是正确的。

于 2009-10-15T15:08:59.690 回答