C
Ich greife diesen Thread nochmal für eine weitere Frage auf.
Kurzform: Das Ziel ist, dass ich am Ende einen Baum/Container/... habe, der beliebig viele Werte eines beliebigen Typs speichern kann.
Beschreibung:
Stichwort Templates.
Ich habe ein Struct für die ID geschrieben und die Operatoren "==", "!=, "<", "<=", ">" und ">=" überladen.
Das Schema der ID ist wie im Beispiel (char)(int)(int)(int).
Jetzt möchte ich alle IDs in einem Baum speichern. Jeder Knoten-Grad steht für den entsprechenden Grad des ID-Schemas (Ich hoffe, es ist klar was ich meine :D) und jeder Knoten speichert einen Wert und kann auf beliebig viele Knoten des nächsten Grades zeigen.
Die Wurzel hat also an sich gar keinen Wert (bzw einen beliebigen), die Knoten des Grades 1 haben nur Chars als Wert und die Knoten der Grade 2-4 haben einen int-Wert.
Jedes Struct bekommt als Template-Parameter den Typ für seinen eigenen Wert (T1) und den Typ des Wertes des nächsten Knotens (T2).
Die nächsten Knoten werden als pointer in einer map gespeichert.
Der Compiler meckert aber beim Build rum und ich versteh auch warum.
Ich weiß aber nicht, wie ich das sinnvoll beheben kann bzw. ob das überhaupt in der Form möglich ist, wie ich mir das vorstelle/erhoffe...
Fehler/Problem:
Mit addNode(IDTreeNode* node) wird ein neuer Knoten an den aktuellen angehängt.
Allerdings müssen ja in der Funktion und in der map die template-Parameter für den anzuhängenden Node mit angegeben werden.
Ich möchte den Baum aber so Typ-unabhängig wie möglich haben. Also muss ich quasi die Typen des anzuhängenden Knotens wissen, bevor ich sie weiß .
Minimalbeispiel:
Der TestCode schaut bis jetzt wie folgt aus:
"main.cpp":
#include "templatetest.h"
int main(int argc, char *argv[])
{
TemplateTest* test = new TemplateTest();
return 0;
}
"templatetest.h":
#include <map>
using namespace std;
template <typename T1, typename T2>
struct IDTreeNode{
IDTreeNode<T1,T2>(T1 value);
bool existNode(T2 value);
void addNode(IDTreeNode* node); //Funktioniert nicht
//void addNode(IDTreeNode<T2,T2>* node); //Funktioniert
T1 getValue();
IDTreeNode* getNode(T2 value);
private:
T1 myValue;
map<T2, IDTreeNode*> myNodes; //Funktioniert nicht
// map<T2, IDTreeNode<T2,T2>*> myNodes; //Funktioniert
};
class TemplateTest
{
public:
TemplateTest();
};
und "templatetest.cpp":
#include "templatetest.h"
TemplateTest::TemplateTest()
{
IDTreeNode<char,int>* NodeStart = new IDTreeNode<char,int>('A');
IDTreeNode<int,int>* Node1 = new IDTreeNode<int,int>(1);
IDTreeNode<int,int>* Node2 = new IDTreeNode<int,int>(2);
NodeStart->pushNewNode(Node1);
NodeStart->getNode(1)->pushNewNode(Node2);
char value1 = NodeStart->getValue();
int value2 = NodeStart->getNode(1)->getValue();
int value3 = NodeStart->getNode(1)->getNode(2)->getValue();
}
template <typename T1, typename T2>
IDTreeNode<T1,T2>::IDTreeNode(T1 value)
{
myValue = value;
}
template <typename T1, typename T2>
bool IDTreeNode<T1,T2>::existNode(T2 value)
{
if(myNodes.count(value) > 0) return true;
return false;
}
//Funktioniert nicht
template <typename T1, typename T2>
void IDTreeNode<T1,T2>::addNode(IDTreeNode *node)
{
myNodes[node->getValue()] = node;
}
//Funktioniert
/*
template <typename T1, typename T2>
void IDTreeNode<T1,T2>::addNode(IDTreeNode<T2,T2> *node)
{
myNodes[node->getValue()] = node;
}
*/
template <typename T1, typename T2>
T1 IDTreeNode<T1,T2>::getValue()
{
return myValue;
}
template <typename T1, typename T2>
IDTreeNode<T2,T2> *IDTreeNode<T1,T2>::getNode(T2 value)
{
return myNodes[value];
}
Frage:
Ist eigentlich klar . Wie löse ich das am besten?
Optimal wäre wohl ein Pointer. Aber gibt es einen, bei dem ich eben nicht den Datentyp angeben muss?
Ich habe es schon mit auto versucht, da meckert der Compiler auch. Vielleicht habe ich auto auch nur falsch benutzt...
Ich hatte auch die Idee, ein zweites template-struct zu bauen, das nur den Wert speichert und an den entsprechenden Knoten gehängt wird, aber an sich habe ich da ja wieder das gleiche Problem. Ich muss für eine Referenz den Typ kennen, den ich ja erst zur Laufzeit kenne...
Ich schreibe den Baum um zu lernen, wie ich mit templates umzugehen habe. Es bringt mir also recht wenig, wenn jemand schreibt "benutz doch diesen Container aus jener lib" .
Viele Grüße
Cherup