Question

J'ai un thread de travail, qui contient une liste des « Actions de la discussion », et fonctionne à travers eux comme quand.

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;

};

Il est normalement appelé comme ceci

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

Ce qui a bien fonctionné jusqu'à ce que

 void TheirClass::enable()

a été changé à

 bool TheirClass::enable()

Malheureusement, nous ne pouvons pas changer à nouveau parce que d'autres choses a besoin du nouveau format, (et ne peut pas différer les surcharges par type de retour seul).

J'ai essayé

myActionThread->addAction( 
    new ThreadAction<TheirClass>(this, 
        reinterpret_cast<void(TheirClass::*)>(&TheirClass::enable)
    )
);

Ce qui semble fonctionner très bien, mais je ne suis pas certain que réinterprétant un pointeur de fonction comme celui-ci est un comportement « défini », quelqu'un peut-il s'il vous plaît conseiller?

Était-ce utile?

La solution

Ceci est certainement pas comportement pris en charge, et peut potentiellement causer votre programme crash.

En fait, vous devez faire un wrapper pour TheirClass::enable() qui aura le bon type de retour. Un simple-liner suffit:

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

Ensuite, appelez:

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

Si vous ne pouvez pas modifier directement TheirClass, puis créez une simple sous-classe ou classe d'aide qui implémente l'emballage.

Autres conseils

Err, de ce que je l'ai compris, vous coulée à partir d'une méthode qui retourne un bool à une méthode qui retourne void?

Cela peut être dangereux, selon la convention d'appel / retour en cours d'utilisation. Vous peut oublier de pop la valeur de retour -. Ou remplacer la valeur d'un registre à la valeur de retour

Pas une bonne idée. Pensez à ajouter un paramètre de modèle supplémentaire pour le type de retour:

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

Ceci est une application de vide de retour .

Je trouve généralement que lorsque la question est de la forme « Est-_______ une bonne idée? » la réponse est presque toujours « NON! »

Ceci est probablement vrai sans contexte.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top