Argumente einer Vorlagen-Klasse
-
Hallo miteinander,
wenn ich eine Vorlagen-Klasse habe, die relativ umfangreich ist, und eine Memberfunktion einen zusätzlichen Parameter benötigt, muss ich dann der ganzen Vorlagen-Klasse zwei geben?
Z.B.
template<class T, class DTO> class class_name { T m_data; // ... public: class_name(T data); // ... void function(DTO dto); };Es gibt in der ganzen Klasse nur eine Funktion die den Parameter DTO benötig. Wenn ich aber folgendes schreibe
template<class T> class class_name { T m_data; // ... public: class_name(T data); // ... template<class DTO>void function(DTO dto); };Setzt der Compiler T für DTO ein und ich bekomme eine Fehlermeldung.
Wie löst man so etwas, bzw. was mache ich falsch?
Bin um jede Hilfe dankbar.Viele Grüße
Knecht
-
Der Codeabschnitt ist korrekt.
Ich könnte den Post hier eigentlich beenden ;), dennoch:
- Wie lautet die Fehlermeldung?
- Wie ist die Implementierung von void function<>?EDIT:
- Wie versuchst Du void function<> aufzurufen?
-
evtl. benutzt du auch einen schlechten compiler, der member templates nicht ausserhalb der klasse definieren kann bsp: VC6.
zumindest sieht es so aus das deine definitionen ausserhalb wären.
-
Hallo miteinander,
der gegebene Code war nur ein vereinfachtes Beispiel. Im Original sieht es so aus.
namespace Tree { typedef unsigned int qtLocCode; template<class T> class qtCell { public: // constructors qtCell(T *Data, qtLocCode xCode = 0, qtLocCode yCode = 0, qtLocCode Level = QT_ROOT_LEVEL, qtCell<T> *Parent = 0); ~qtCell(void); // ... template<class DTO> void qtBranch(DTO *dto); // branch this Node void qtUnbranch(void); // remove all sons from here class qtBranchError {}; // class for exception handling class qtTreeSizeError {}; private: int key; // HACK this initializer can be removed if the comparison of addresses in the neighbour searching dialog works. qtLocCode xLocCode; // X locational code qtLocCode yLocCode; // Y locational code qtLocCode level; // Cell level in hierarchy (smallest cell has level 0) qtCell *parent; // Pointer to parent cell qtCell **children; // Pointer to first of 4 contiguous child cells T *data; // Application specific cell data //------------------------------------------------------------------------------- // Maximum quadtree depth and related constants //------------------------------------------------------------------------------- static qtLocCode QT_N_LEVELS; // Number of possible levels in the quadtree (def. = 16) static qtLocCode QT_ROOT_LEVEL; // Level of root cell (def. = QT_N_LEVELS - 1) // For converting positions to locational codes (QT_MAX_VAL = 2^QT_ROOT_LEVEL) static double QT_MAX_VAL; // 32768.0 static unsigned int counter; }; // Declaration of helper functions // ... } template<class T, class DTO> void Tree::qtCell<T>::qtBranch(DTO *dto) /* The qtBranch() function checks first if the cell is already branched and if so it throws an exception. Second it checks if the level of the current cell is zero. This mean that the tree has reached its max height and qtBranch() throws an exception. Then it calls the function T.Branch() to get the data for the new cells. Further it determis the childs location codes and creates them. */ { if (children) throw qtBranchError(); if (!level) throw qtTreeSizeError(); T **Data = data->Branch(dto); qtLocCode Level = level - 1; qtLocCode branch = 1 << Level; children = new qtCell *[4]; children[0] = new qtCell(Data[0], xLocCode, yLocCode, Level, this); children[1] = new qtCell(Data[1], xLocCode | branch, yLocCode, Level, this); children[2] = new qtCell(Data[2], xLocCode, yLocCode | branch, Level, this); children[3] = new qtCell(Data[3], xLocCode | branch, yLocCode | branch, Level, this); // delete only the pointer to the data not the data themselfe. delete[] Data; Data = 0; }und die zugehörige Fehlermeldung ist die folgende.
c:\MitsubishiQuadTree.h(364) : error C2244: 'qtBranch': Keine Übereinstimmung für Funktionsdefinition mit vorhandener Deklaration gefunden Definition 'void Tree::qtCell<T>::qtBranch(T2 *)' Vorhandene Deklarationen 'void Tree::qtCell<T>::qtBranch(DTO *)'Als Compiler verwende ich MS VS2003.net und die Definitionen stehen im gleichen File wie die Deklaration.
Herzlichen Dank für die Hilfe
Viele GrüßeEDIT: Ich rufe die funktion folgendermaßen auf
(*temp)->qtBranch(ppd);wobei temp ein iterator auf ein qtCell<T> object ist, da ich die leaves in einer Liste verwalte...
ppd ist eine Struktur die die nötigen parameter zusammen fasst.
-
auf den ersten blick würde ich sagen so
template< class T> template< class DTO> void Tree::qtCell<T>::qtBranch(DTO *dto) { // ...
-
Es gibt ja auch keine Funktion qtBranch in der Klasse qtCell<T, DTO> sondern nur eine Funktion qtBranch<DTO> in der Klasse qtCell<T> ;). Die korrekte Definition müsste wie folgt lauten:
template<class T> // "äusseres" Template template<class DTO> // "inneres" Template Tree::qtCell<T>::qtBranch(DTO* dto) { //... }Damit weiss der Compiler, dass es sich um das Template qtBranch<DTO>(DTO*) innerhalb des Templates qtCell<T> handelt.
-
Hallo miteinander,
genau das war's.Herzlichen Dank für die schnelle Hilfe.
Viele Grüße
Knecht