2009-07-07 17 views
5

novato aquí todavía experimentando con plantillas. Intentando escribir un mensaje plantilla de clase de procesamientoClase de plantilla dentro de la plantilla de clase en C++

template <typename T> class MessageProcessor { 

    //constructor, destructor defined 
    //Code using t_ and other functions 
foo(void) { 

//More code in a perfectly fine method 
} 
    private: T *t_ 

}; 

Todo definido en un archivo de encabezado. He construido y probado mi clase y todo está bien. Ahora, estoy tratando de hacer esto:

template <typename T> class MessageProcesor { 

    //Same stuff as before 

foo(void) { 
//Same code as before in foo, but one new line: 
    t_->getMessageSender<MessageType>(); 

} 

private: T *t_; 
}; 

Sin embargo, esta línea me da un error del mal de tipo expresión antes símbolo '>'.

He agregado los archivos de cabecera necesarios para definir qué es un tipo de mensaje. He usado esta función muchas veces antes, solo que no en este contexto.

Sospecho que al compilador no le gusta el hecho de que la función de la plantilla esté completamente definida (¿especializada?) Dentro de una plantilla de clase indefinida (¿no especializada?). No estoy completando lo que hace que una plantilla sea 'especializada'. La mayoría de las explicaciones se centran en los conceptos de "completo" o "parcial", pero no lo que lo especializa en primer lugar.

Disculpa, si quieres ver más código. No tengo acceso a Internet en el trabajo y ahí es donde estoy haciendo esto, así que tengo que poner todo en mi 'scratchpad' mental y llevarlo a casa.

+2

Publique el código de la función getMessageSender aquí. –

+0

comida no tiene un tipo de devolución, ese es su problema –

+0

Usted es todo correcto en sus observaciones. Sin embargo, esos fueron errores tipográficos. El problema real era la falta de la palabra clave 'plantilla' como respondida por Faisal – user106740

Respuesta

9

Su función miembro 'foo' necesita un tipo de retorno y tiene que utilizar la palabra clave 'plantilla' cuando se utiliza plantillas de miembros en expresiones dependientes (expresiones cuyo significado depender directa o indirectamente de un parámetro de plantilla genérica)

t_->template getMessageSender<MessageType>(); // ok 
t_->getMessageSender<MessageType>(); // not ok 

Quizás este ejemplo lo ayude a apreciar cuando una plantilla de miembro necesita precedida por la palabra clave 'plantilla' [Nota: en interés de la simetría siempre puede usar el prefijo 'plantilla' en las plantillas miembro, pero es opcional cuando se usa en una expresión no dependiente.

struct MyType 
{ 
    template<class T> void foo() { } 
}; 

template<class U> 
struct S 
{ 
    template<class T> 
    void bar() 
    { 
    MyType mt; // non-dependent on any template parameter 
    mt.template foo<int>(); // ok 
    mt.foo<int>(); // also ok 

    // 't' is dependent on template parameter T 
    T t; 
    t.template foo<int>(); // ok 
    t.foo<int>(); // not ok 

    S<T> st; // 'st' is dependent on template parameter T 
    st.template foo<int>(); // ok 
    st.foo<int>(); // not ok 


    S<MyType> s; // non-dependent on any template parameter 
    s.bar<int>(); // ok 
    s.template bar<int>(); // also ok 

    } 

}; 

Espero que ayude.

+0

¿En qué compilador necesita hacer eso? –

+0

@Edouard - El estándar requiere el prefijo 'plantilla' solo cuando se accede a las plantillas miembros desde un identificador que depende de un parámetro de plantilla: la mayoría de los compiladores deberían tener este derecho ya que esto ha sido parte del estándar desde '98 - en '03 modificaron las reglas en aras de la simplicidad para que pueda usarla en todos los accesos a plantillas de miembros, y además de los compiladores EDG (que en su mayoría lo hacen bien), no lo he comprobado en ninguno de los otros compiladores, por favor, déjenme saber si tienes –

0

Probablemente, MessageType no se conoce en ese momento. ¿Te estás perdiendo una inclusión, una resolución de espacio de nombres o una declaración?

si no es así, ¿cómo se declara getMessageSender, y cómo es MessageType?

Generalmente, en C++ no es un problema si T no se conoce en ese punto (bueno ... es complicado, pero aún así).

Además, el mensaje de error generalmente contiene el tipo para el que se intenta proteger. Intente publicar el mensaje de error completo al menos.

0

¿Tiene otras llamadas similares a métodos como getMessageSender que están personalizadas?

t_->getMessageSender<MessageType>(); 
2

agregar la palabra clave template entre -> y el nombre del método de la plantilla:

t_->template getMessageSender<MessageType>(); 
0

Es sólo el tipo de retorno de la función que le falta. El miembro t_ está completamente definido.

Una especialización de una plantilla es una versión 'especial' de su implemento para argumentos de plantilla específicos. Un ejemplo: std::vector es la versión especializada del genérico std::vector.

Una especialización parcial es una implementación de su código genérico donde no se proporcionan todos los argumentos de la plantilla.

0

Esto funciona bien en el compilador de Visual Studio 2010.

class One 
{ 
public: 
    void newFoo() ; 
    template < class T > void foo() 
    { 
     T obj ; // obj is dependent on template parameter 
     obj.newFoo() ; // and this works 
    } 
} 

Solo para mantener la respuesta actualizada !!!

Cuestiones relacionadas