2

「スレッド アクション」のリストを保持するワーカー スレッドがあり、それらを 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)
    )
);

これはうまく機能しているように見えますが、このような関数ポインターの再解釈が「定義済み」の動作であるかどうかはわかりません。誰かアドバイスしてもらえますか?

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

エラー、私が理解したことから、あなたは a を返すメソッドから?boolを返すメソッドにキャストしています。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

私は一般的に、質問が「_______は良い考えですか?」という形式のものであることに気づきます。答えはほぼ常に「NO!」です。

これはおそらく文脈なしに真実です。

于 2009-10-15T15:08:59.690 に答える