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?


  • Mod

    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


Anmelden zum Antworten