Pregunta

Tengo una clase con una función "Adjuntar" que acepta un objeto de función y lo almacena en una colección. La clase en sí está templated en la firma de la función. Algo como esto:

template<class Signature>
class Event
{
public:

 void Attach(boost::function<Signature> signature)
 {
  MySignatures.push_back(signature);
 }

private:

 std::list<boost::function<Signature>> MySignatures;
};

Para demostrar el uso, considere la siguiente clase:


class Listening
{
public:

 int SomeFunction(int x, int y, int z); 
};

Para pasar a la función de Listening en Event, que tendría que escribir:


 Event<int(int, int, int)> myEvent;
 Listening myListening;

 myEvent.Attach(boost::bind(boost::mem_fn(&Listening::SomeFunction), &myListening, _1, _2, _3));

Así que en lugar de hacerlo para cada caso que puede ser propenso a errores, escribo un conjunto de macros, de la siguiente manera:


 #define EventArgument0(x, y)  boost::bind(boost::mem_fn(x), y)
 #define EventArgument1(x, y)  boost::bind(boost::mem_fn(x), y, _1)
 #define EventArgument2(x, y)  boost::bind(boost::mem_fn(x), y, _1, _2)
 #define EventArgument3(x, y)  boost::bind(boost::mem_fn(x), y, _1, _2, _3)
 #define EventArgument4(x, y)  boost::bind(boost::mem_fn(x), y, _1, _2, _3, _4)

 etc.

y luego puedo escribir:


 myEvent.Attach(EventArgument3(&Listening::SomeFunction, &myListening));

que es mucho más fácil de leer (creo). Ahora a mi pregunta: ¿cómo puedo escribir en su lugar:


 myEvent.Attach(EventArgument(&Listening::SomeFunction, &MyListening));

o incluso mejor:


 myEvent.Attach(&Listening::SomeFunction, &myListening);

, de manera que el evento Adjuntar mágicamente se unen correctamente con el número apropiado de argumentos que figura en el (en este ejemplo, int(int, int, int))? Estoy abierto a cualquier plantilla mágica meta-programación que tiene en mente aquí.

Gracias.

Editar: resulta que no necesito boost::mem_fn aquí, porque boost::bind es equivalente, por lo que en mi macro que puede utilizar:

bind(&MyClass::Hello, myClass, _1, _2, _3);

, en lugar de:

bind(mem_fn(&MyClass::Hello), myClass, _1, _2, _3);

La pregunta sigue siendo, sin embargo:? Cómo pasar &MyClass::Hello a la clase de evento y la plantilla de uso sobrecarga para manejar la _1, _2, _3, etc. implicado por el prototipo de función utilizado a la plantilla de la clase Event

¿Fue útil?

Solución

sobrecarga Attach para diferentes números de parámetros en la función miembro:

template<typename R,typename T,typename U>
void Attach(R (T::*pmf)(),U* p))
{
    Attach(boost::bind(pmf,p));
}

template<typename R,typename T,typename U,typename A1>
void Attach(R (T::*pmf)(A1),U* p))
{
    Attach(boost::bind(pmf,p,_1));
}

template<typename R,typename T,typename U,typename A1,typename A2>
void Attach(R (T::*pmf)(A1,A2),U* p))
{
    Attach(boost::bind(pmf,p,_1,_2));
}

Si usted necesita para manejar las funciones miembro const demasiado, entonces tendrá un segundo conjunto de sobrecargas.

Otros consejos

Hacer Attach() una plantilla le permitirá hacer lo que usted está apuntando. El código se complica pero vamos a usted la llama de la manera deseada.

template<typename A1>
void Attach(A1 a1);

template<typename A1, typename A2>
void Attach(A1 a1, A2 a2);

template<typename A1, typename A2, typename A3>
void Attach(A1 a1, A2 a2, A3 a3);

template<typename A1, typename A3, typename A4>
void Attach(A1 a1, A2 a2, A3 a3, A4 a4);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top