2010-03-01 7 views
8

Me gustaría crear una interfaz de plantilla para las clases de manejo de datos en mis proyectos.Transfiriendo la firma del método como parámetro de plantilla a una clase

puedo escribir algo como esto:

template <class T> 
class DataHandler 
{ 
    public: 
     void Process(const& T) = 0; 
}; 

Entonces, supongamos, que definir una clase de esta manera:

class MyClass: public DataHandler<int> 
{ 
    void Process(const int&) { /* Bla-bla */ } 
} 

Ahora, vamos a la pregunta, ¿hay algún modo de definir la interfaz de mi plantilla en la forma en que como parámetro recibirá no solo el tipo T, sino la firma completa de la función Process().

me gustaría algo de trabajo de esta manera:

class MyClass: public DataHandler<void (int&)> 
{ 
    void Process(const int&) { /* Bla-bla */ } 
} 

¿Es posible? Sé que, por ejemplo, boost :: signal recibe los parámetros de la plantilla de esta manera, pero, si entiendo correctamente, usan mucha magia negra allí.

Respuesta

12

Sí, puede. Pero en C++ 03, está obligado a copiar/pegar código para cada número de parámetros (lo que no está nada mal, ya que aquí no necesitará sobrecargas para const/non-const, etc. ¡Ya se conoce el constnes!).

template<typename FnType> 
struct parm; 

template<typename R, typename P1> 
struct parm<R(P1)> { 
    typedef R ret_type; 
    typedef P1 parm1_type; 
}; 

template <class T> 
class DataHandler 
{ 
    typedef typename parm<T>::ret_type ret_type; 
    typedef typename parm<T>::parm1_type parm1_type; 

    public: 
     virtual ret_type Process(parm1_type t) = 0; 
}; 

class MyClass: public DataHandler<void (const int&)> 
{ 
    void Process(const int&) { /* Bla-bla */ } 
}; 

En C++ 0x, usted será capaz de escribir

template <class T> 
class DataHandler; 

template<typename R, typename ... P> 
class DataHandler<R(P...)> 
{ 
    public: 
     virtual R Process(P... t) = 0; 
}; 

class MyClass: public DataHandler<void (const int&)> 
{ 
    void Process(const int&) { /* Bla-bla */ } 
}; 

lo mucho mejor!

+0

Ahora la pregunta sigue siendo: ¿cuántos años tardarán hasta que podamos poner las plantillas variadic a uso diario en el trabajo. Saber cuánto más simple podría ser ... –

+0

¿Y cómo debería cambiarlo para admitir más de un parámetro en la función Process() en la interfaz DataProducer? Quiero decir, me gustaría apoyar algo como DataHandler Lev

+0

@Lev, sospecho que tendrás que especializar parcialmente 'DataHandler' en el tipo de función para que obtengas la declaración de la función' Process' correcto también 'boost :: function' utiliza el preprocesador para generar el código necesario, pero para proyectos propios y algunos usos, no es útil (en mi opinión) introducirse en ese tema que es probable que ya no necesite. Así que solo copie/pegue 4 veces y termine :) –

Cuestiones relacionadas