[Gelöst] TemplateObjekt als Übergabe in Funktion



  • Hallo,

    ich habe eine Klassentemplate für Zeitmessungen:

    template <class T> class MeasureGeneric {
       MeasureGeneric<T>(T var, const int &length) {...}
    };
    

    Nun möchte ich in einer anderen Klasse (class Variable) ein solch erstelltes Objekt-Template übergeben, um es auszuwerten. Dazu habe ich in der Klasse Variable eine solche Methode definiert:

    class Variable
    {
    public:
      void setMeasureBasicOperations(MeasureGeneric<class T> &varOps);
    };
    

    Die Objekte erstelle ich nun mit folgendem Aufruf z.B.:

    double varDouble = 0;
    MeasureGeneric<double> varClass(varDouble, var.getLength());
    

    Soweit klappt dies auch. Möchte ich jetzt allerdings auswerten, was ich mit

    Variable var;
    var.setMeasureBasicOperations(varClass);
    

    tue, bekomme ich allerdings vom gcc die Fehlermeldung zurück:

    error: no matching function for call to Variable::setMeasureBasicOperations(MeasureGeneric<double>&)’
    candidates are: void Variable::setMeasureBasicOperations(MeasureGeneric<T>&)
    

    Ich habe den Verdacht, dass er nicht erkennt, dass in der Methode "setMeasureBasicOperations(...)" Templates verwendet werden. Wie muss ich dies ändern, damit der Compiler dies korrekt erkennt?

    Vielen Dank schon mal.

    Viele Grüße,

    Tobias



  • Du müsstest entweder die Variable -Klasse oder zumindest die betroffene Methode zu einem Template machen - oder du änderst den Parameter in MeasureGeneric<double> .



  • Im Parameter der Funktion in variable muss Class t bereits durch einen Typen ersetzt werden, der erwartet wird. Das würde so nur gehn wenn variable auch ein template wäre, jedoch würde die Funktion den Typen erwarten mit dem die Instanz von var selbst definiert wurde z.b bei Var<int> var; ein int.



  • Mist zu langsam. Tja Smartphone Tastatur... 🙄



  • Ah, ich verstehe. In dem Falle würde ich nur die Methode zum Template machen wollen.
    Müßte dann, wenn ich es richtig verstehe, etwa so aussehen:

    class Variable
    {
    public:
       template <class S> void setMeasureBasicOperations(MeasureGeneric<class T> &varOps);
    };
    

    Ich habe deswegen "class S" genommen, da GCC sonst moniert, dass template "T" nach der Definition von "class" genommen wird:

    error: using template type parameter ‘T’ after ‘class’
    

    Allerdings bin ich etwas ratlos, wie ich das aufrufen soll, da hierbei

    double varDouble = 0;
    MeasureGeneric<double> varClass(varDouble, var.getLength());
    var.setMeasureBasicOperations<double>(varClass);
    

    der GCC meckert, dass er die Funktion nicht findet?

    error: no matching function for call to ‘Variable::setMeasureBasicOperations(MeasureGeneric<double>&)’
    

    Vielen Dank auf jeden Fall für die schnelle Hilfe.



  • Sir_Tobias schrieb:

    Ah, ich verstehe. In dem Falle würde ich nur die Methode zum Template machen wollen.
    Müßte dann, wenn ich es richtig verstehe, etwa so aussehen:

    class Variable
    {
    public:
       template <class S> void setMeasureBasicOperations(MeasureGeneric<class T> &varOps);
    };
    

    Nein, dort hinten gehört kein "class" hin:

    template <class T> void setMeasureBasicOperations(MeasureGeneric<T> &varOps);
    


  • Vielen, vielen Dank für die schnelle Hilfe.
    Jetzt klappt das auch mit den Aufrufen.

    Ein allgemeine Frage hätte ich noch zur Code-Übersichtlichkeit:

    Gibt es auch die Möglichkeit, die Methoden-Implementation der Templates in die CPP-Dateien auszulagern? Es wird sonst schnell unübersichtlich, wenn man die gesamte Implementation in die Header-Datei stopfen muss.

    Wenn ich versuche, die Implementation auszulagern, beschwert sich der Linker über "undefined references". Gibt es da die Möglichkeiten von sogenannten "forward declarations"?

    Viele Grüße,

    Tobias



  • Das geht nur, wenn du alle später zu verwendenden Spezialisierungen mit angibst.
    Alternativ gibt es auch die Möglichkeit, die Template-Definitionen in eine impl-Datei auszulagern, die du am Ende des Headers einbindest.



  • Sir_Tobias schrieb:

    Gibt es auch die Möglichkeit, die Methoden-Implementation der Templates in die CPP-Dateien auszulagern?

    Nein. Die Definitionen müssen zur Compilezeit immer sichtbar sein, d.h. wenn der Compiler den Header gelesen hat, muss er in der gleichen Übersetzungseinheit auch die Definitionen finden.

    Manche machen es so, dass sie die Definitionen in eine separate Datei schreiben und diese am Ende des Headers includen.
    Den gleichen Effekt hat es, die definitionen im header, aber außerhalb der Klassendefinition zu schreiben:

    template <class T>
    class Foo
    {
    public:
      Foo(T const&);
    
      void bar(int i);
    };
    
    template <class T>
    Foo<T>::Foo(T const& t) { /* ... */ }
    
    template <class T>
    void Foo<T>::bar(int i) { /* ... */ }
    


  • Ah, ok, vielen vielen Dank für die Hilfe!


Anmelden zum Antworten