Pregunta

Tengo una clase que he estado a condición de que la verdad es que no quiero cambiar, pero yo quiero extender. Soy un novato patrón y la plantilla de experimentar con un patrón decorador aplicado a una clase de plantilla. clase de plantilla contiene un puntero a miembro (si entiendo correctamente la semántica) en otra clase. El puntero a miembro es el deserializer de un istream XML. El tipo 'T' es el tipo de documento XML para deserializar.

template <typename T> class B {
public:
  typedef std::auto_ptr<T> MYFUN( 
    std::istream&, const std::string&, const std::string& );

public:
  B<T>( MYFUN* p );

private:
  MYFUN *fptr;
  std::string aString1;
  std::string aString2;

};

El typedef parece extraño para mí después de leer http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.5 , y sin embargo esta clase parece funcionar bien como está. No hay ningún #defines adicionales en el archivo de cabecera proporcionado, así que esto es un poco misterioso para mí.

Ahora trato de extenderlo, como decorador porque quiero hacer un poco más trabajo en el objeto devuelto por auto_ptr MYFUN:

template <typename T>
class D : public class B<T>
{
  D( B<T>::MYFUN *fPtr, B<T> *providedBase ); //compiler complaint
  //Looks like B
  private:
    B* base_;

};

template <typename T>
D<T>::D( B<T>::MYFUN *p, B<T> *base ) //compiler complaint
:
B<T>::B( p ), base_(providedBase)
{ }

Al intentar compilar este, consigo una queja de sintaxis en las dos líneas que se muestran. El error es algo así como "espera ')' en *". No hay ninguna queja sobre MYFUN siendo indefinido.

Cuando me re-definir el puntero a miembro de D con la misma firma como en D, es decir.

//change MYFUN to NEWFUN in D)
typedef std::auto_ptr<T> MYNEWFUN( 
    std::istream&, const std::string&, const std::string& );

Esto funciona. Prefiero no tener que hacer esto para cada D / decorador que podría hacer de B. traté de realizar el typedef más globalmente, pero no pude conseguir la sintaxis correcta debido al parámetro de plantilla siendo indefinido.

¿Fue útil?

Solución

El error de compilación se debe al hecho de que el compilador no puede decir que estamos hablando de un tipo.

Probar:

D( typename B<T>::MYFUN *fPtr, B<T> *providedBase );

y

template <typename T>
D<T>::D( typename B<T>::MYFUN *p, B<T> *base )

Ver: la sección de plantillas de C ++ FAQ Lite para más detalles acerca de por qué esto es necesario, pero el resumen es que debido a la posibilidad de especialización de plantilla, no hay manera para que el compilador para asegurarse de que B<T>::MYFUN se refiere en realidad a un tipo.

Otros consejos

La definición de la typedef MYFUN en B se realiza con visibilidad privada. D no será capaz de acceder a él. Si lo cambia a protegida o pública, ¿tiene entonces el trabajo?

template <typename T> class B {
  protected:
    typedef std::auto_ptr<T> MYFUN( 
      std::istream&, const std::string&, const std::string& );
...
};

El problema que veo con esto es que B :: MYFUN es un privado typedef.

Por lo tanto, cualquier clase que hereda no se puede acceder a él.

Cambie esto a:

template <typename T> class B 
{  
public:
   typedef std::auto_ptr<T> MYFUN(     std::istream&, const std::string&, const std::string& );
public:  
   B<T>( MYFUN* p );
private:  
   MYFUN *fptr;  
std::string aString1;  
std::string aString2;
};
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top