Template typename declaration



  • Was bedeutet der zweite Parameter in der folgenden Template deklaration?

    template<typename T, //the first parameter is used
    T Root, //in the declaration of the second one and
    template<T> class Buf> // in the declaration of the third one
    class Structure;
    

    das dritte ist nen template template parameter, aber ist das zweite ein nontype parameter oder was ist der Vorteil dieses Root parameters?


  • Mod

    Die "Bedeutung" von etwas ist eine Frage der Programmlogik. Da hier nichts mit Root (oder irgendeinem der anderen Parameter) gemacht wird, bedeutet es erst einmal gar nichts.

    Wenn deine eigentliche Frage lauten sollte, was das für ein Sprachkonstrukt ist: Ein Template darf ja auch (ganzzahlige) Werte als Parameter haben, in der Art von:

    template<int I> class Foo{};
    

    Aber das int in diesem Beispiel darf natürlich auch wieder ein templatisierter Typ sein. Das wurde hier gemacht, indem gesagt wurde, dass Root vom vorher gegebenen Typ T sein soll. Damit könnte man beispielsweise so etwas machen:

    template <typename T, T value> class Foo {};
    
    int main()
    {
        Foo<int, 5> foo;	
        Foo<int (*)(), &main> bar;
    }
    

    Ob es dafür sinnvolle Anwendungsszenarien gibt, ist eine andere Frage. Wichtiger ist eher die Botschaft, dass einer der vorne stehenden Templateparameter benutzt werden kann, die Parameter weiter hinten genauer einzuschränken. Das braucht man andauernd überall.



  • Danke für deine Antwort, also ist es wie ich gedacht habe ein nontype template paramter, nur dass statt bspw. nem int der zuvor vorgebenene Datentyp verwendet wird.

    gehe ich richtig in der Annahme, dass einfach template type parameter im gegensatz zu nontype parametern nie eine Referenz oder Pointer sein können?

    also das beispielsweise folgendes nicht erlaubt ist

    template <typename T*>
    void foo(T)
    

  • Mod

    Typenparameter von Templates können alle Typen sein. Zeiger und Referenzen sind auch Typen. Ob ein solcher Typ ein Zeiger Typ ist (sofern man diese denn gesondert behandeln möchte), muss dann der Macher des Templates prüfen. Die übliche Art und Weise dafür wäre (partielle) Spezialisierung. Das ist wahrscheinlich auch das, woran du hier gedacht hast, aber die Syntax stimmt nicht.

    template <typename T> struct Foo; // Reine Deklaration, könnte so nicht instantiiert werden, außer wir definieren es noch irgendwo
    
    template <typename T> struct Foo<T*> // Spezialisierung für Zeiger
    {
      // Hier der Code für die Zeigerspezialisierung
    };
    

    Wie du eine Referenz als Werteparameter an ein Template übergeben möchtest, musst du mir mal erklären.



  • das meinte ich ja, das funktioniert nur bei nontype template parametern...

    Ist hier der erste Parameter ein template parameter und der zweite ein unnamed nontype parameter?

    template<typename T, T*>
    

    oder worin unterscheidet sich dieser Syntax zu

    template<typename T, T* root>
    

  • Mod

    @sewing sagte in Template typename declaration:

    das meinte ich ja, das funktioniert nur bei nontype template parametern...

    Ja, natürlich. Einen Wert als Pointer zu übergeben, das wäre ein komisches Konzept. Du kannst natürlich einen Pointer auf etwas einfach als Wert übergeben, denn ein Zeiger selbst ist auch ein Wert.

    Ist hier der erste Parameter ein template parameter und der zweite ein unnamed nontype parameter?

    template<typename T, T*>
    

    oder worin unterscheidet sich dieser Syntax zu

    template<typename T, T* root>
    

    Es ist das was du sagst. Der Unterschied ist doch offensichtlich und du nennst ihn selbst: Beim zweiten Beispiel hat der zweite Parameter einen Namen, über den er angesprochen werden könnte, beim ersten ist er halt da, aber könnte in dem Template nicht benutzt werden (Er muss dann natürlich trotzdem vom Nutzer angegeben werden und es wäre auch jeder unterschiedliche Wert eine eigene Spezialisierung, auch wenn der Wert nirgends benutzt wird)


Anmelden zum Antworten