2009-07-07 7 views
5

noob hier noch mit Vorlagen experimentieren. Versuchen, eine Nachrichtenverarbeitungsklassenvorlage zu schreibenTemplate-Klasse innerhalb der Klassenvorlage in 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_ 

}; 

Alle in einer Header-Datei definiert. Ich habe meine Klasse gebaut und getestet und alles ist gut. Nun, ich versuche, dies zu tun:

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_; 
}; 

Doch diese Linie ist mir einen Fehler von schlechten Ausdruck-Typ vor dem ‚>‘ Token.

Ich habe die notwendigen Header-Dateien hinzugefügt, um zu definieren, was ein MessageType ist. Ich habe diese Funktion schon lange benutzt, nur nicht in diesem Zusammenhang.

Ich vermute, dass der Compiler nicht die Tatsache mag, dass die Template-Funktion vollständig (spezialisiert?) Innerhalb einer undefinierten Klassenvorlage (unspezialisiert?) Definiert ist. Ich bin nicht ganz grok, was eine Vorlage "spezialisiert" macht. Die meisten Erklärungen konzentrieren sich auf die Begriffe "voll" oder "partiell", aber nicht auf das, was sie in erster Linie spezialisiert.

Entschuldigung, wenn Sie mehr Code sehen möchten. Ich habe keinen Internetzugang bei der Arbeit und da mache ich das, also muss ich alles in meinen mentalen "Notizblock" legen und nach Hause bringen.

+2

Post getMessageSender Funktionscode hier. –

+0

Essen hat keinen Rückgabetyp, das ist dein Problem –

+0

Sie sind alle in Ihren Beobachtungen korrekt. Das waren jedoch Tippfehler. Das eigentliche Problem war das Fehlen des Schlüsselworts 'Vorlage', wie von Faisal beantwortet – user106740

Antwort

9

Ihre Member-Funktion ‚foo‘ einen Rückgabetyp benötigt und Sie müssen das Schlüsselwort ‚Vorlage‘ verwenden, wenn Sie Mitglied Vorlagen in der abhängigen Ausdrücke (Ausdrücke, deren Bedeutung verläßt direkt oder indirekt auf einem generischen Template-Parametern)

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

Vielleicht hilft Ihnen dieses Beispiel, wenn eine Elementvorlage mit dem Schlüsselwort 'Vorlage' vorangestellt werden muss [Hinweis: Im Interesse der Symmetrie können Sie immer das Präfix 'Vorlage' auf Mitgliedervorlagen verwenden, aber es ist optional, wenn es für einen nicht abhängigen Ausdruck verwendet wird.

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 

    } 

}; 

Hoffe, dass hilft.

+0

Auf welchem ​​Compiler müssen Sie das tun? –

+0

@Edouard - Der Standard erfordert das Präfix 'template' nur beim Zugriff auf Member-Templates aus einem Bezeichner, der von einem Template-Parameter abhängt - die meisten Compiler sollten dieses Recht bekommen, da dies seit '98 - in '03 Teil des Standards war die Regeln der Einfachheit halber, so dass Sie sie für alle Mitgliedervorlagenzugriffe verwenden können - und abgesehen von den EDG-Compilern (die das meistens richtig machen), habe ich es bei keinem der anderen Compiler überprüft - bitte lassen Sie mich Wissen Sie, wenn Sie haben. –

0

Wahrscheinlich ist MessageType zu diesem Zeitpunkt nicht bekannt. Vermissen Sie ein Include, eine Namensraumauflösung oder eine Deklaration?

Wenn das nicht ist, wie ist getMessageSender deklariert, und wie ist MessageType?

Im Allgemeinen ist es in C++ kein Problem, wenn T zu diesem Zeitpunkt nicht bekannt ist (naja ... es ist kompliziert, aber immer noch).

Auch die Fehlermeldung enthält normalerweise den Typ, für den versucht wird, zu bestätigen. Versuchen Sie, mindestens die vollständige Fehlermeldung zu senden.

0

Haben Sie ähnliche Aufrufe von Methoden wie getMessageSender, die templated sind?

t_->getMessageSender<MessageType>(); 
2

Fügen Sie das Schlüsselwort template zwischen -> und dem Namen der Template-Methode:

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

Es ist nur der Rückgabetyp Ihrer Funktion, die vermisst. Das Element t_ ist vollständig definiert.

Eine Spezialisierung einer Vorlage ist eine "spezielle" Version Ihrer Implementierung für bestimmte Vorlagenargumente. Ein Beispiel: std::vector ist die spezialisierte Version des generischen std::vector.

Eine teilweise Spezialisierung ist eine Implementierung Ihres generischen Codes, bei dem nicht alle Vorlagenargumente bereitgestellt werden.

0

Dies funktioniert einwandfrei auf Visual Studio 2010-Compiler.

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

Nur um die Antwort auf dem neuesten Stand zu halten !!!