Pregunta

Tengo una clase que usa functores como unidades de trabajo. Acepta una referencia a un functor en su método Run (). Para permitir que esta clase funcione en cualquier functor, todos estos functors deben derivarse de mi clase de functor base que se ve así:

class baseFunctor{

public:
    virtual void operator()()=0;
    virtual baseFunctor Clone()=0;
};

Esto funciona, sin embargo, obviamente, restringe estos functores a tener un método de operador que devuelve vacío y no acepta parámetros. Necesito poder aceptar un functor en mi clase que pueda tomar cualquier tipo de parámetros y devolver cualquier cosa. Aparentemente es factible pero parece que no puedo encontrar la manera de hacerlo. He considerado el uso de plantillas, herencia múltiple, pero me siento frustrado por el hecho de que la clase que necesita ejecutar este functor debe poder aceptar cualquier tipo, por lo que aceptaré el tipo de clase base y, por lo tanto, no sabré el tipo real del functor.

Se agradecería cualquier sugerencia sobre qué camino tomar.

¿Fue útil?

Solución

¿Cómo sabrá la clase que llama al functor qué parámetros proporcionar y qué hacer con el valor de retorno, si corresponde?

Otros consejos

Entonces, si estoy leyendo esto correctamente, tienes un "Patrón de visitante". Puede ser bueno que mires hacia arriba.

Alguien necesita saber de qué tipo es el functor para darle argumentos. A menudo con los functores, los argumentos se asignan a campos de la clase derivada, y operator () operará en esos campos. Es decir, el método tonto que llama al functor y no sabe nada al respecto recibe el cierre (método más argumentos en una clase) por parte de alguien más informado.

Si desea que los funtores genéricos tomen múltiples argumentos en el operador (), las plantillas lo llevarán a la mitad, pero necesitará uno por aridad.

Estoy de acuerdo con Neil. Su clase principal tiene que saber qué parámetros pasar y qué valor de retorno esperar de estos funtores. ¿Puede simplemente escribir su " functor " ¿A una clase apropiada que admita la función con los argumentos y el valor de retorno necesarios?

class baseFunctor
{
};

class functor1x2: public baseFunctor
{
public:
    virtual void* execute(void*, void*);

}

class MainClass
{
public:
   void Execute(baseFunctor* ipFunctor)
   {
      functor1x2* lpFunctor1x2 = dynamic_cast<functor1x2*>(ipFunctor);
      if(lpFunctor1x2)
      {
         lpFunctor1x2->execute(NULL, NULL);
      }
   }
}

No estoy seguro de qué podría lograrse con este enfoque que no podría lograrse más fácilmente con el patrón Visitante, como señaló Drew.

Si está abierto a usar la biblioteca Boost (www.boost.org), puede encontrar Boot.Bind y Boost.Function de particular interés. Los he usado en el pasado para lograr algo muy similar a lo que está discutiendo.

Si usa Boost.Bind, puede realizar el curry en los funtores para tener en cuenta las diferencias entre el número de argumentos que el functor espera y el número de argumentos que espera el método Run (es decir, cero). El código que crea el functor tendría que vincular los argumentos a valores específicos y, por lo tanto, crear un functor de cero argumentos que se pueda pasar a Run ().

MV

¿Por qué quieres devolver el functor? ¿Estás almacenando algún estado también? Se agradecerán algunos detalles más, ya que no está muy claro qué es exactamente lo que desea hacer.

Si planea usar la herencia, busque Tipos de Devolución Covariantes (y Idioma de Constructor Virtual ).

Ahora, por el problema: el problema realmente no es pasar un funtor sino una aplicación de funtor. Puede echar un vistazo a boost :: lambda y boost :: parámetro también.

Creo que quieres un argumento de puntos suspensivos, como varargs para C ++.

Quizás la función std :: tr1 :: es interesante para ti?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top