Frage zu template instantiations



  • Hallo Community,

    Ich würde gerne wissen, was derartige preceeding vor einer Klassendefinition genau bedeuten

    template <
            typename kern_type 
            >
        class rvm_trainer 
        {
    
        public:
            typedef kern_type kernel_type;
            typedef typename kernel_type::scalar_type scalar_type;
            typedef typename kernel_type::sample_type sample_type;
            typedef typename kernel_type::mem_manager_type mem_manager_type;
            typedef decision_function<kernel_type> trained_function_type;
    

    Wie ich das gelernt habe:

    rvm_trainer ist eine template class, die bei Deklarierung einer Variablen vom Typ rvm_trainer spezialisiert wird, zB. durch

    rvm_trainer<kernel_type> trainer{};
    

    Also gilt von jetzt an sozusagen kernel_type = kernel_type. Im public Bereich wird das dann auch direkt typedefed. Nebenfrage: Ginge hier auch die using direktive?

    typedef kern_type kernel_type;
    

    Womit ich jetzt aber Verständnisprobleme habe, ist der folgende Codeblock

    typedef typename kernel_type::scalar_type scalar_type;
            typedef typename kernel_type::sample_type sample_type;
            typedef typename kernel_type::mem_manager_type mem_manager_type;
            typedef decision_function<kernel_type> trained_function_type;
    

    was vor allem an den typedefs in Verbindung mit den typenames liegt. Und was genau macht hier der Scope resolution operator?

    Ich bin verwirrt 😕


  • Mod

    Sewing schrieb:

    Nebenfrage: Ginge hier auch die using direktive?

    Ja.

    was vor allem an den typedefs in Verbindung mit den typenames liegt.

    Der wahre Nutzen von typename.

    Und was genau macht hier der Scope resolution operator?

    Er löst den Scope auf 😉



  • Danke, das lese ich mir mal durch. Hoffe das beantwortet meine Fragen



  • Und warum wird hier nicht direkt statt

    typedef kern_type kernel_type;
    

    der template parameter kernel_type statt kern_type genannt?


  • Mod

    Namen von Templateparametern sind nach außen nicht sichtbar.



  • was ist hier außen? Außerhalb des Class scopes?



  • Ja. Alles was nicht die Instanzierung Definition von rvm_trainer ist. Aussen halt 🤡

    EDIT: Unfug korrigiert.


  • Mod

    Um mal konkret zu werden, da dir anscheinend nicht klar ist, was hier erreicht werden soll:
    Später soll es möglich sein, dass der Benutzer der fertigen Klasse die ganzen Typdefinitionen benutzen kann. Denk an std::vector als ein typisches Beispiel, wo es so etwas gibt. Siehe hier unter Member tpyes. Das wird beim vector ziemlich ähnlich programmiert sein wie bei deiner Klasse hier. Und nützlich ist das, wenn man dann später so etwas wie

    typedef vector<int> container_typ;
    

    macht und dann den Typ braucht, der überhaupt in dem Container gespeichert ist. Und in anderen Fällen, wie dem Iteratortyp, braucht man solche Definitionen auch ohne typedef.



  • OK danke Euch!

    Also ist diese Notation nötig, wenn ich später mit einem Objekt der Klasse Attribute/Methoden der Klasse zugreifen möchte, mit der die template Klasse instantiiert wurde. Dazu der Scope resolution operator, auf den der Bezeichner folgen muss,

    typedef kern_type kernel_type; 
            typedef typename kernel_type::scalar_type scalar_type; 
            typedef typename kernel_type::sample_type sample_type; 
            typedef typename kernel_type::mem_manager_type mem_manager_type; 
            typedef decision_function<kernel_type> trained_function_type;
    

    der in der Klasse existiert (vielleicht ebenfalls als typedef), mit der instantiiert wird. typename muss davor, um Doppeldeutigkeiten zu vermeiden und typedefs optional davor. Ich könnte doch auch weiterhin kernel_type::scalar_type verwenden nicht?

    Und ob ich dann kernel_type oder kern_type für die restlichen Deklarationen oben verwende, ist egal?


  • Mod

    Sewing schrieb:

    Also ist diese Notation nötig, wenn ich später mit einem Objekt der Klasse Attribute/Methoden der Klasse zugreifen möchte, mit der die template Klasse instantiiert wurde. Dazu der Scope resolution operator, auf den der Bezeichner folgen muss,

    Ich weiß nicht, was du meinst. Klingt wirr.

    typedefs optional davor.

    Nein, die sind nicht optional, du möchtest schließlich einen typedef machen. Du könntest alternativ using in seiner neuen typedef-artigen Bedeutung benutzen, aber dann wäre die Syntax

    using scalar_type = typename ernel_type::scalar_type;
    

    Ich könnte doch auch weiterhin kernel_type::scalar_type verwenden nicht?

    Wie, was, wo? Wovon redest du?

    Und ob ich dann kernel_type oder kern_type für die restlichen Deklarationen oben verwende, ist egal?

    Da die beiden hier gleich sind, macht es keinen Unterschied. Der Unterschied ist philosophischer Natur, da sich die Definition kernel_type = kern_type ja auch irgendwann einmal ändern könnte (Wobei das in diesem Beispiel eher unwahrscheinlich klingt). Dann ist nämlich die Frage, ob dann die Folgetypedefs sich auf kernel_type oder direkt auf den Templateparameter kern_type beziehen. Vom Namen der typedefs her, hier wohl eher Ersteres.


Anmelden zum Antworten