Pregunta

novato aquí sigue experimentando con las plantillas. Tratando de escribir una plantilla de clase de procesamiento de mensajes

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 se define en un archivo de cabecera. 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 añadido los archivos de cabecera necesarios para definir qué es MessageType. He usado esta función muchas veces antes, pero no en este contexto.

Sospecho que el compilador no le gusta el hecho de que la función de plantilla está completamente definido (especializada?) Dentro de una plantilla de clase no definida (no especializado?). No estoy totalmente Grokking lo que hace que una plantilla 'especializada'. La mayoría de las explicaciones se centran en los conceptos de 'total' o 'parcial', pero no lo que hace que se especializó en el primer lugar.

Las disculpas si les gustaría 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 'bloc de notas' mental y llevarla a casa.

¿Fue útil?

Solución

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

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

Tal vez este ejemplo le ayudará a apreciar cuando una plantilla miembro de debe para ir precedidos por la 'plantilla' palabra clave [Nota: en el interés de simetría siempre se puede usar el prefijo 'plantilla' en el miembro plantillas, 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.

Otros consejos

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

t_->template getMessageSender<MessageType>();

Probablemente, MessageType no se conoce en ese punto. ¿Falta una incluyen, una resolución o una declaración de espacio de nombres?

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

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

Además, el mensaje de error por lo general contiene el tipo para el que se pretende que se insantiated. Tratar de publicar el mensaje de error completo, al menos.

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

t_->getMessageSender<MessageType>();

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' para su implemento argumentos específicos de la plantilla. Un ejemplo:. std::vector es la versión especializada de la std::vector genérico

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

Esto funciona bien en Visual Studio 2010 compilador.

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

Sólo para mantener actualizada la respuesta !!!

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