¿Reinterpretar un puntero de función miembro es una "buena idea"?
-
21-09-2019 - |
Pregunta
Tengo un hilo de trabajo, que contiene una lista de 'Acciones de subproceso' y las analiza como un cuándo.
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;
};
normalmente se llama asi
myActionThread->addAction(
new ThreadAction<TheirClass>(this, &TheirClass::enable)
);
Lo cual funcionó bien hasta
void TheirClass::enable()
fue cambiado a
bool TheirClass::enable()
Lamentablemente, no podemos volver a cambiarlo porque otras cosas necesitan el nuevo formato (y las sobrecargas no pueden diferir solo por el tipo de retorno).
lo intenté
myActionThread->addAction(
new ThreadAction<TheirClass>(this,
reinterpret_cast<void(TheirClass::*)>(&TheirClass::enable)
)
);
Lo que parece funcionar bien, pero no estoy seguro de que reinterpretar un puntero de función como este sea un comportamiento "definido", ¿alguien puede aconsejarme?
Solución
Esto es definitivamente no comportamiento apoyado, y puede potencialmente causar su programa se bloquee.
Básicamente, lo que necesita para hacer un contenedor para TheirClass::enable()
que tendrá el tipo de retorno adecuado. Un simple de una sola línea será suficiente:
public:
void enableWrapper() { enable(); };
A continuación, llamar a:
myActionThread->addAction(
new ThreadAction<TheirClass>(this, &TheirClass::enableWrapper)
);
Si no se puede modificar directamente TheirClass
, a continuación, crear una subclase simple o clase de ayuda que implementa el envoltorio.
Otros consejos
Err, por lo que he entendido, usted es de fundición de un método que devuelve un bool
a un método que devuelve void
?
Esto puede ser peligroso, dependiendo de la llamada / de regresar de convenciones en uso. Usted podría se olvide de hacer estallar el valor de retorno -. O anular el valor de un registro con el valor de retorno
No es una buena idea. Considerar la adición de un parámetro de plantilla adicional para el tipo de retorno:
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;
};
Esta es una aplicación de retorno void .
general, me parece que cuando la cuestión es de la forma "es _______ una idea buena?" la respuesta es casi siempre "NO!"
Esto es probablemente cierto, sin contexto.