2010-12-10 11 views
2

一部コードメソッドハンドラの暗黙のキャスト?

typedef void (*EventHandler) (EventObject* sender, EventArgs* args, void* closure); 

class Control 
{ 
void AddHandler(int eventId, EventHandler handler, void* data) 
} 

class SubControl 
{ 
static void mousemove_cb(EventObject* sender, MouseEventArgs* calldata, void* closure); 
} 

エラーここ

error C2664: 'Control::AddHandler' : cannot convert parameter 2 from 'void (__cdecl *)(EventObject *,MouseEventArgs *,void *)' to 'EventHandler' 

エラーを生成するラインである:

control.AddHandler(MouseMoveEvent, mousemove_cb, 0); 

説明

問題は、MouseEventArgsがEventArgsのサブクラスであることです。だから、自動キャスティングし、私のメソッドを正確な 'イベント引数'で登録する方法はありますか?

+0

おそらく 'MouseEventArgs'がEventArgs''から派生したコードは、これを判断できるように、ヘッダが正しく設定されている? – acron

答えて

1

C++テンプレートは、この問題を解決することができ、正しい型に最初argsを変換する必要があり、これを使用してください。:

struct Control 
{ 
    //Note this change! 
    template<typename TEventHandler> 
    void AddHandler(int eventId, TEventHandler handler, void* data); 
}; 

struct SubControl 
{ 
    static void mousemove_cb(EventObject* sender, MouseEventArgs* calldata, void* closure); 
    SubControl() 
    { 
     Control control; 
     control.AddHandler(0, mousemove_cb, 0); 
    } 
}; 
1

実際には言語によって禁止されているため、エラーが発生します。それが可能であったなら、これは型システムに穴を開けます。このコードを検討してください:

struct EventArgs {}; 

void f(EventHandler handler) 
{ 
    EventArgs args; 
    handler(0, &args, 0); 
} 

struct MouseEventArgs : EventArgs { void GetMousePosition(); }; 

void g(EventObject* sender, MouseEventArgs* args, void* closure) 
{ 
    args->GetMousePosition(); 
} 

f(g); // oops... g calls GetMousePosition on EventArgs 

幸いにもコンパイラはこのバグをキャッチします。

+0

これは質問に答えるでしょうか?問題は 'MouseEventArgs'と' EventArgs'があるということではないです基本的に異なるタイプのものはありませんか? – acron

+0

@acron:いいえ、それが他のタイプのベースであっても不可能ですエル。編集を参照してください。 – ybungalobill

0

いいえ、自動キャストはありません。タイプは一致しなければならない。あなたは、2つの異なる方法でAddHandlerに署名を変更することができます:それはvoid*を受け入れるようにして、タイプを機能するように、正確なポインタへの変換を強制しない

  1. セット。
  2. Tを受け入れるテンプレートにAddHandlerを変換し、正しいパラメータであるt(sender, args,...)を呼び出すことができます。ここで、2番目のパラメータは引数です。 。ただし、コールは、それがマウスイベントである場合(例えば、tを呼び出す前に、手動MouseEventArgsに変換
関連する問題