2010-12-10 9 views
2

Certains CodeCoulée implicite pour le gestionnaire de méthodes?

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

L'erreur

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

Voici la ligne qui produit l'erreur:

control.AddHandler(MouseMoveEvent, mousemove_cb, 0); 

Description de

Le problème est que MouseEventArgs est une sous-classe d'EventArgs! Alors, y a-t-il un moyen d'avoir un casting automatique et d'enregistrer ma méthode avec le paramètre 'Event args'?

+0

on peut supposer que '' MouseEventArgs' dérive de EventArgs' et vos en-têtes sont correctement configurés de telle sorte que le code peut déterminer cela? est-ce – acron

Répondre

1

C++ modèle pourrait résoudre ce problème utiliser..:

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

Vous obtenez l'erreur car elle est en fait interdite par la langue. Si cela avait été possible, cela ouvrirait un trou dans le système de types. Considérez ce code:

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 

Heureusement, le compilateur attrape ce bogue.

+0

répondre à la question? est-ce que le problème ne '' MouseEventArgs' et EventArgs' sont – acron

+0

@acron: Non, c'est impossible même si l'on est la base de la er. Voir l'édition. – ybungalobill

0

Non, il n'y a pas de distribution automatique. Les types doivent coïncider. Vous pouvez changer la signature du AddHandler de deux façons différentes:

  1. Set pour accepter un void* et ne force la conversion au pointeur exact type de fonction.
  2. Convertissez le AddHandler en un modèle qui accepte un type T afin qu'il puisse être appelé avec les paramètres corrects, t(sender, args,...), où le deuxième paramètre est les arguments. Cependant, l'appel doit convertir d'abord le args au bon type (par exemple, si elle est un événement de la souris, le convertir en MouseEventArgs manuellement avant d'appeler t
Questions connexes