KlassenTemplate-Funktion Implementieren

Enumerator

Mitglied Kamel
Abend!

Frage: Wenn man in einer Header-Datei eine Template-Klasse wie z.B. ...

Code:
template<typename size_type, typename value_type>
class cBeispiel
{
public:
            cBeispiel(void); ~cBeispiel(void);
            value_type operator() (size_type _item) const;
            value_type& operator[] (size_type _item);
private:
             value_type* _Values;
             size_type _size;
};

... deklariert und jetzt in einer *.cpp - Datei die Funktionen/Methoden implementieren möchte, allerdings unabhängig vom gewälten Typ ... WIE MACHT MAN DAS DEM COMPILER KAR ? ... Versuche wie ...

Code:
value_type cBeispiel::operator() (size_type _item) const
{
             //...
}

... etc. sind zum Scheitern verurteilt, also wie stellt man das an?

Thx im Vorraus
Enum
 
Hallo,

die Bezeichner size_type und value_type sind zunächst nur in der Klassendefinition verfügbar. Deshalb kann man sie nicht so einfach außerhalb verwenden.

Du musst deine Methode explizit als Template-Methode deklarieren:
Code:
template<typename size_type, typename value_type>
value_type cBeispiel<size_type, value_type>::operator() (size_type _item) const
{
// …
}
Dabei kannst du natürlich in der Methode wiederum andere Typnamen verwenden. Dass hier wieder size_type und value_type stehen, ist reiner Zufall :)

Grüße,
Matthias
 
Hätte ich eigentlich selber 'drauf kommen müssen.
Naja, war ich wohl zu doof. Danke !!

Gruß
Enum
 
Zuletzt bearbeitet:
Jetzt hab ich ein neues Problem: Ich bekomme Fehlermeldungen über nicht aufgelöste externe Verweise, und zwar für jeden Member der Klasse.
error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: __thiscall cBeispiel<unsigned int>::~cBeispiel<unsigned int>(void)"
Muss ich in der Klassendefinition etwas beachten? Oder hat das andere Ursachen?

Gruß
Enum
 
Zuletzt bearbeitet:
@Matthias

Ja und ja. Daher ist mir das ja so schleierhaft.
Code:
template<typename size_type>
cBeispiel<size_type>::~cBeispiel (void)
{
// …
}

Wenn ich es so probiere, bekomme ich Warnungen von wegen "alter Stil":
Code:
template<typename size_type>
cBeispiel<size_type>::~cBeispiel<size_type> (void)
{
// …
}

Aber der "neue" Stil, der mir empfohlen wird, ist der oben. Also: muss ich in der Header etwas beachten? Oder spinn' ich einfach nur?

Gruß
Enum
 
Hallo,

aus einigen Usenet-Beiträgen geht hervor, dass der Compiler (nicht erst der Linker) bei der Verwendung von Templates die Implementation der Methoden kennen muss. Es sollte also klappen, wenn man die Implementation entgegen der Gewohnheit mit in die Headerdatei aufnimmt.

Was allerdings auch zu klappen scheint: in die Datei mit der Implementation der Klassenmethoden beispielsweise Folgendes einfügen:
Code:
template class cBeispiel<unsigned int>;
Ich bin allerdings überfragt, warum das auch funktioniert ;) Vielleicht kann da ein Profi mehr dazu sagen.

Grüße,
Matthias
 
Das Problem ist gelöst !!
Vielen Dank!

Allerdings habe ich es etwas anders gemacht: ich habe in der Implementierungsdatei nicht ...
template class cBeispiel<unsigned int>;
... sondern ...
Code:
template class cBeispiel<typename>;
eingefügt.

Die erste Variante würde ja für jeden möglichen Wert eine eigene Zeile erfordern, was den Codeumfang unverantwortlich in die Höhe treiben würde - schließlich wird für jedes Template der gesamte Code neu geschrieben. (Stichwort: Template Induced Code Bloat)

Die Variante mit dem direkten Einfügen der Implementierung in die Header ist offensichtlich auch nicht zweckmäßig.

Dennoch vielen Dank, ohne Deine Anregungen würde ich jetzt wohl verzweifeln

Gruß
Enum
 
Hallo,

Allerdings habe ich es etwas anders gemacht: ich habe in der Implementierungsdatei nicht ...

... sondern ...
Code:
template class cBeispiel<typename>;
eingefügt.
Das ergibt bei mir folgende Fehlermeldungen (MinGW, GCC 3.4.5):
Code:
cBeispiel.cpp:13: error: using `typename' outside of template
cBeispiel.cpp:13: error: using `typename' outside of template
cBeispiel.cpp:13: error: template argument 1 is invalid
Na ja, Hauptsache bei dir klappt es :)

Grüße,
Matthias
 

Neue Beiträge

Zurück