重新解释成员函数指针是一个“好主意”吗?

发布于 2024-08-07 09:00:13 字数 883 浏览 8 评论 0原文

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

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

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

草莓味的萝莉 2024-08-14 09:00:13

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

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

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

然后调用:

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

如果您无法直接修改 TheirClass,则创建一个实现包装器的简单子类或辅助类。

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.

阿楠 2024-08-14 09:00:13

呃,根据我的理解,您正在从返回 bool 的方法转换为返回 void 的方法?

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

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.

卖梦商人 2024-08-14 09:00:13

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

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

这是 返回void

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.

萝莉病 2024-08-14 09:00:13

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

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文