Kleines großes Problem mit Templateargumenten
-
Hi,
ich habe da ein Problem mit Templateargumenten.
#include <iostream> #include <string> template <std::string value_one, typename value_two> class value_pair { public: value_pair () { std::cout << value_one << " = " << value_two << std::endl; } }; int main () { value_pair<"wert eins", 555> mein_test; return 0; }Ich bekomme bei diesem Code mehrere Fehlermeldungen:
1>------ Build started: Project: templatetest, Configuration: Debug Win32 ------
1>Compiling...
1>main.cpp
1>main.cpp(4) : error C2993: 'std::string' : illegal type for non-type template parameter 'value_one'
1>main.cpp(15) : error C2762: 'value_pair' : invalid expression as a template argument for 'value_one'
1> main.cpp(5) : see declaration of 'value_pair'
1>main.cpp(15) : error C2133: 'mein_test' : unknown size
1>main.cpp(15) : error C2512: 'value_pair' : no appropriate default constructor available
1>Build log was saved at "file://Debug\BuildLog.htm"
1>templatetest - 4 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========Ich bekomme gesagt, das ich std::string nicht als Typ nehmen kann für parameter 1 und das die Instanz eine unbekannte größe sein würde.
Das mit std::string versteh ich, dadurch das es eine dynamische Klasse ist also den Speicher zur Laufzeit im RAM reserviert, ersetze ich std::string durch char[128] bekomme ich die erste Warnung nicht, doch kompilieren tut er immer noch nicht, wegen eines ungültigen Ausdrucks

Wie kann ich den Code zum laufen bringen? Bitte keine Verweise auf andere Klassen, ich möchte diese Klasse zu laufen bringen
Bringt mir ja nichts andere klassen zu benutzen, wenn ich das Prinzip nicht verstehen. 
-
Was soll value_two sein? Du führst es als templateabhängigen Typ ein und benutzt es dann im Konstruktor als Objekt.
Das du std::string nicht verwenden darst, hat übrigens nichts mit dynamischer Speicherverwaltung zu tun. Du darfst generell keine Klassen verwenden.
-
Michael E. logged out schrieb:
Das du std::string nicht verwenden darst, hat übrigens nichts mit dynamischer Speicherverwaltung zu tun. Du darfst generell keine Klassen verwenden.
warum? gibt es eine möglichkeit es doch zu tun?
-
C++'ler schrieb:
Michael E. logged out schrieb:
Das du std::string nicht verwenden darst, hat übrigens nichts mit dynamischer Speicherverwaltung zu tun. Du darfst generell keine Klassen verwenden.
warum? gibt es eine möglichkeit es doch zu tun?
non-type-Templateargumente müssen konstante Ausdrücke sein (schließlich soll das Ergebnis wohldeterminiert sein) - zudem gibt es weiter Einschränkungen:
Erlaubt sind nur Ausdücke integralen Typs oder Zeiger auf Funktionen oder statische Objekte, die für den Linker sichtbar sind (external linkage).
Möglich wäre hier z.B.:template <const char* value_one, int value_two> class value_pair ... // const impliziert internal linkage, wenn wir nichts dagegen unternehmen: extern const char wert1[] = "wert eins"; int main () { value_pair<wert1, 555> mein_test; return 0; }
-
Danke für die gute Antwort camper!
Eine Frage habe ich jedoch: Was ist wenn ich anstatt const char* einfach char[128] nehme? Dann müsste doch genügend Speicher vorhanden sein, oder?
-
*push it*
-
char[128] ist ein Array und damit ein zusammengesetzter Datentyp => geht nicht. Die einzig gueltigen Typen sind wie schon oben gesagt:
- char, int, short, long (signed und unsigned)
- pointer auf Objekte, Funktionen, Member und Memberfunktionen
Parameter muessen ausserdem const sein bzw. um genauer zu sein, zur Compilezeit ermittelt werden koennen.Folgende Typen gehen NICHT:
- float, double & Co
- arrays
- structs und Klassen
- variable