Anfängerfrage zu Templates
-
Hallo,
ich will eine Klasse schreiben, die eigentlich nur Werte eines verschiedenen Datentyps aufnehmen soll und bei Bedarf wieder zurück geben soll. Soweit so gut: Bei Instaziieren des Objektes, unterscheide ich die unterschiedlichen Typen durch überladenen Methoden. Nur die Rückgabe des Wertes bereitet mir ein paar Probleme. Ich dachte Templates waren das mittel der Wahl, aber irgendwie klappt das nicht.
Ich poste mal die Klassendeklaration:#include <string> using namespace std; template <typename T> class ALValue { public: ALValue(int param); ALValue(double param); ALValue(string param); string GetType(); T GetValue(); virtual ~ALValue(); private: string type; };g++ bringt mir dann einen Fehler an der Stelle class ALValue. Sinngemäß irgendwas mit fehlende Template Parameter.
Könnte mir einer weiterhelfen was falsch ist? Oder hat vielleicht jemand für mein Problem eine bessere Lösung (evtl. mit Vererbung)?Gruß und Danke
-
Sinngemäß wird wohl irgendwo ein Template-Parameter fehlen.
Willst Du genaue Informationen, lohnt es sich die genaue Fehlermeldung anzugeben.
-
Schau dir mal boost::any an, das koennte dein Problem loesen. Und noch eine KLeinigkeit, die mir aufgefallen ist: du benutzt ein "using namespace std" im Zusammenhang mit templates. Da temapltes aber eigentlich immer in headern definiert werden, benutzt du folglich unsing namespace std in einem header, und das solltest du tunlichst vermeiden.
-
Hallo nochmal,
also hier ist die genaue Fehlermeldung vom COmpiler:
**** Build of configuration Debug for project ALValue_Test **** make -k all Building file: ../ALValue.cpp Invoking: GCC C++ Compiler g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"ALValue.d" -MT"ALValue.d" -o"ALValue.o" "../ALValue.cpp" ../ALValue.cpp:4: Fehler: »template<class T> class ALValue« ohne Template-Parameter verwendet ../ALValue.cpp:4: Fehler: ISO-C++ verbietet Deklaration von »ALValue« ohne Typ ../ALValue.cpp: In function »int ALValue(int)«: ../ALValue.cpp:4: Fehler: »int ALValue(int)« als andere Symbolart redeklariert ../ALValue.h:5: Fehler: vorherige Deklaration von »template<class T> class ALValue« ../ALValue.cpp:6: Fehler: »type« wurde in diesem Gültigkeitsbereich nicht definiert ../ALValue.cpp: At global scope: ../ALValue.cpp:9: Fehler: »template<class T> class ALValue« ohne Template-Parameter verwendet ../ALValue.cpp:9: Fehler: ISO-C++ verbietet Deklaration von »ALValue« ohne Typ ../ALValue.cpp: In function »int ALValue(double)«: ../ALValue.cpp:9: Fehler: »int ALValue(double)« als andere Symbolart redeklariert ../ALValue.h:5: Fehler: vorherige Deklaration von »template<class T> class ALValue« ../ALValue.cpp:11: Fehler: »type« wurde in diesem Gültigkeitsbereich nicht definiert ../ALValue.cpp: At global scope: ../ALValue.cpp:14: Fehler: »template<class T> class ALValue« ohne Template-Parameter verwendet ../ALValue.cpp:14: Fehler: ISO-C++ verbietet Deklaration von »ALValue« ohne Typ ../ALValue.cpp: In function »int ALValue(std::string)«: ../ALValue.cpp:14: Fehler: »int ALValue(std::string)« als andere Symbolart redeklariert ../ALValue.h:5: Fehler: vorherige Deklaration von »template<class T> class ALValue« ../ALValue.cpp:16: Fehler: »type« wurde in diesem Gültigkeitsbereich nicht definiert ../ALValue.cpp: At global scope: ../ALValue.cpp:19: Fehler: »template<class T> class ALValue« ohne Template-Parameter verwendet ../ALValue.cpp: In function »std::string GetType()«: ../ALValue.cpp:21: Fehler: »type« wurde in diesem Gültigkeitsbereich nicht definiert ../ALValue.cpp: At global scope: ../ALValue.cpp:24: Fehler: expected constructor, destructor, or type conversion before »::« token make: *** [ALValue.o] Fehler 1 Building file: ../main.cpp Invoking: GCC C++ Compiler g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"main.d" -MT"main.d" -o"main.o" "../main.cpp" ../main.cpp: In function »int main()«: ../main.cpp:9: Fehler: Templateargument 2 ist ungültig ../main.cpp:9: Fehler: Templateargument 4 ist ungültig ../main.cpp:9: Fehler: invalid type in declaration before »;« token ../main.cpp:10: Fehler: expected type-specifier before »ALValue« ../main.cpp:10: Fehler: assignment of read-only location ../main.cpp:10: Fehler: ungültige Umwandlung von »int*« in »char« ../main.cpp:10: Fehler: expected `;' before »ALValue« ../main.cpp:11: Fehler: expected type-specifier before »ALValue« ../main.cpp:11: Fehler: assignment of read-only location ../main.cpp:11: Fehler: ungültige Umwandlung von »int*« in »char« ../main.cpp:11: Fehler: expected `;' before »ALValue« ../main.cpp:12: Fehler: expected type-specifier before »ALValue« ../main.cpp:12: Fehler: assignment of read-only location ../main.cpp:12: Fehler: ungültige Umwandlung von »int*« in »char« ../main.cpp:12: Fehler: expected `;' before »ALValue« ../main.cpp:13: Fehler: expected type-specifier before »ALValue« ../main.cpp:13: Fehler: assignment of read-only location ../main.cpp:13: Fehler: ungültige Umwandlung von »int*« in »char« ../main.cpp:13: Fehler: expected `;' before »ALValue« ../main.cpp:14: Fehler: Basisoperand von »->« ist kein Zeiger make: *** [main.o] Fehler 1 make: Das Target »all« wurde wegen Fehlern nicht aktualisiert. Build complete for project ALValue_TestIch poste auch mal noch den kompletten Testcode (ist nicht so viel
). Vielleicht weiß dann einer von euch weiter:#include "ALValue.h" #include <stdio.h> #include <map> using namespace std; int main () { map<string,ALValue*> TestMap; TestMap["Test1"] = new ALValue("Test"); TestMap["Test2"] = new ALValue(1); TestMap["Test3"] = new ALValue(1.1); TestMap["Test4"] = new ALValue("Test2"); printf("%s\n",TestMap["Test1"]->GetType().c_str()); return 0; }#include "ALValue.h" ALValue::ALValue(int param) { type = "int"; } ALValue::ALValue(double param) { type = "double"; } ALValue::ALValue(std::string param) { type = "string"; } std::string ALValue::GetType() { return type; } ALValue::~ALValue() { }#include <string> template <typename T> class ALValue { public: ALValue(int param); ALValue(double param); ALValue(std::string param); std::string GetType(); T GetValue(); virtual ~ALValue(); private: std::string type; };Wenn ich die beiden Zeilen mit der Template rauslasse, funktioniert es dann auch, aber dann kann ich eben nicht typunabhänig den Wert zurückgeben.
Boost werde ich mir mal anschauen, aber irgendwie wäre es mir lieber wenn ich eine eigene Lösung hätte. Kann ja eigentlich auch nicht so viel sein, denke ich mal.
Das mit dem Namespace habe ich auch rausgenommen. Danke für den Hinweis :-).Gruß
-
Es fehlt
#include "ALValue.cpp" oder wie deine Datei auch immer heißtunter
#include <string> template <typename T> class ALValue { public: ALValue(int param); ALValue(double param); ALValue(std::string param); std::string GetType(); T GetValue(); virtual ~ALValue(); private: std::string type; }; #include "ALValue.cpp" <<== fehlt
-
Genau hier ist dein Problem:
map<string,ALValue*> TestMap;Du musst den Template-Parameter schon bei der Benutztung angeben. Das ist der Sinn von Templates.
Es könnte z.B. so gehen.
map<string,ALValue<int>* > TestMap;Übrigens: Nein, dein Problem ist nicht ganz so einfach. Wenn du schnell mit deinem Problem weiter kommen willst, solltest du Boost::any nehmen.
-
class BasicALValue { virtual ~BasicALValue() {}; }; template <typename T> class ALValue : public BasicALValue { public: ALValue( T Value ) : m_Value(Value) { } ~ALValue(); { } void SetValue( T& NewValue ) { m_Value = NewValue; } T GetValue() { return m_Value; } private: T m_Value; };Main.cpp
int main () { std::map<std::wstring, BasicALValue*> TestMap; TestMap[L"Test1"] = new ALValue<int>(10); TestMap[L"Test2"] = new ALValue<std::wstring>(L"Toll!"); TestMap[L"Test3"] = new ALValue<bool>(true); return 0; }so sollte es einfach funktionieren, ohne den Umweg über Strings gegangen zu sein.
hier:
http://www.gamedev.net/reference/programming/features/enginuity3/page2.asp
ist übrigens noch ein netter Link der soetwas ähnliches macht wie du möchtest'hoffe das hilft!