Pergunta

Eu tenho um tópico de trabalhador, que contém uma lista de 'ações de thread', e trabalha através deles como um quando.

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 é chamado assim

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

Que funcionou bem até

 void TheirClass::enable()

foi alterado para

 bool TheirClass::enable()

Infelizmente, não podemos alterá -lo novamente, porque outras coisas precisam do novo formato (e sobrecarga não podem diferir apenas pelo tipo de retorno).

Eu tentei

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

O que parece funcionar muito bem, mas não tenho certeza de que reinterpretar um ponteiro de função como esse é um comportamento "definido", alguém pode aconselhar?

Foi útil?

Solução

Isso é definitivamente não comportamento suportado e pode potencialmente fazer com que seu programa trave.

Basicamente, você precisa fazer um invólucro para TheirClass::enable() Isso terá o tipo de retorno adequado. Uma linha simples simples será suficiente:

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

Então ligue:

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

Se você não pode modificar TheirClass Diretamente, crie uma subclasse ou classe auxiliar simples que implementa o invólucro.

Outras dicas

Err, pelo que eu entendi, você está lançando de um método que retorna um bool para um método que retorna void ?

Isso pode ser perigoso, dependendo da convenção de chamada/retorno em uso. Você poderia Esqueça de exibir o valor de retorno - ou substituir o valor de um registro com o valor de retorno.

Não é uma boa ideia. Considere adicionar um parâmetro de modelo adicional para o 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 é uma aplicação de retornar vazio.

Geralmente acho que quando a pergunta é da forma "é _______ uma boa ideia?" A resposta é quase invariavelmente "não!"

Provavelmente isso é verdade sem contexto.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top