質問

「スレッドアクション」のリストを保持し、それらを 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;

};

通常はこのように呼ばれます

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

これは問題なく動作しているように見えますが、このように関数ポインターを再解釈することが「定義された」動作であるかどうかわかりません。誰かアドバイスしてください。

役に立ちましたか?

解決

これは間違いであるの動作をサポートし、することができ、潜在的にクラッシュするプログラム原因ではない。

基本的に、あなたは適切な戻り値の型を持っていますTheirClass::enable()のラッパーを作成する必要があります。シンプルなワンライナーで十分です。

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

次に呼び出します:

myActionThread->addAction(
    new ThreadAction<TheirClass>(this, &TheirClass::enableWrapper)
);
あなたが直接TheirClassを変更できない場合は、

、その後、実装ラッパーます。

という単純なサブクラスまたはヘルパークラスを作成します

他のヒント

えー、私が理解したところによると、あなたは を返すメソッドからキャストしているようです。 bool を返すメソッドに void ?

これは、使用されている呼び出し/戻り規則によっては危険である可能性があります。あなた かもしれない 戻り値をポップするのを忘れるか、レジスタの値を戻り値でオーバーライドします。

はない良いアイデア。戻り値の型のための追加のテンプレートパラメータを追加することを検討します:

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

これは

私は一般質問の形式である場合いることを見つける「_______良いアイデアですか?」答えはほとんど常に "NO!" です。

このコンテキストなしで、おそらく本当です。

scroll top