Spezialisierung von Methoden in Templates



  • asfdlol schrieb:

    der fehler ist in der zeile 48. eine instanziierung "Vielleichtstd::string" und ein aufruf dieser methode geht schief, weil das ducktyping gewisse anforderungen hat (auf ungleichheit mit einem int prüfbar sein), welche ein std::string nicht erfüllen kann. erklär vielleicht was dieses klassentemplate überhaupt bewirken soll, damit man dir weiter helfen kann...

    Das Template soll für "alle" Datentypen funktionieren, d.h für alle Ganzzahlen und Gleitkommazahlen funktioniert das wie gewünscht...

    Nun ist es so wie du gesagt hast, ich instnziere die Template Klasse mit std::string, weil aber "string / string" undefiniert ist, wollte ich eine Spezialisierte Methode für strings haben die mir ein leeres Objekt von Typ Vielleichtstd::string zurückgibt.

    int main(int argc, char** argv) {
        Vielleicht<string> hallo("Hallo");
        Vielleicht<string> welt;
        //welt = 25;
        cout << hallo.text() << endl;
        cout << welt.text() << endl;
    
        welt = string("Welt");
        cout << welt.was() << endl;
    
        Vielleicht<string> cut;
        cut = hallo + string(" ") + welt;
        cout << cut.text() << endl;
    
        cut = hallo / welt;
        cout << cut.text() << endl;
    
        return 0;
    }
    


  • SeppJ schrieb:

    Falsche Signatur der Spezialisierung, daher passt sie nicht. Sie muss lauten:

    template<>
    Vielleicht<std::string> Vielleicht<std::string>::operator/(const Vielleicht<std::string>&)
    

    👍 danke das war die Lösung, jetzt habe ich meine gewünschte Ausgabe



  • Mein Edit kam ein wenig spät...


  • Mod

    Wenn die Klasse nur für Ganzzahltypen Sinn macht, wieso machst du dann eine Spezialisierung für eine andere Klasse? Das verbirgt doch nur den Fehler, dass die Aktion keinen Sinn macht. Das ist ein Fall für einen Compilezeitfehler, keinen Laufzeitfehler! Das finde ich ganz schlechtes Design.

    Weitere Designfehler:
    -manuelle Speicherverwaltung in einer Klasse, deren Aufgabe das nicht ist. Halte die Daten in einer auf manuelle Speicherverwaltung spezialisierten Klasse. Hier scheinen sich dafür die fertigen Standardklassen vector oder valarray anzubieten. Zumindest unter der Annahme, dass da später mal mehr als ein Wert verwaltet werden soll. Denn warum man einen Wrapper um einen einzelnen arithmetischen Wert haben sollte wäre mir total rätselhaft.
    -A propos valarray: Kann's sein, dass du gerade valarray nachprogrammierst?



  • SeppJ schrieb:

    Wenn die Klasse nur für Ganzzahltypen Sinn macht, wieso machst du dann eine Spezialisierung für eine andere Klasse? Das verbirgt doch nur den Fehler, dass die Aktion keinen Sinn macht. Das ist ein Fall für einen Compilezeitfehler, keinen Laufzeitfehler! Das finde ich ganz schlechtes Design.

    Weitere Designfehler:
    -manuelle Speicherverwaltung in einer Klasse, deren Aufgabe das nicht ist. Halte die Daten in einer auf manuelle Speicherverwaltung spezialisierten Klasse. Hier scheinen sich dafür die fertigen Standardklassen vector oder valarray anzubieten. Zumindest unter der Annahme, dass da später mal mehr als ein Wert verwaltet werden soll. Denn warum man einen Wrapper um einen einzelnen arithmetischen Wert haben sollte wäre mir total rätselhaft.
    -A propos valarray: Kann's sein, dass du gerade valarray nachprogrammierst?

    Nein das ist eine Praktikum Aufgabe, ich denke mal das soll auf evtl. auftretende Fehler hindeuten bzw. das diverse Operationen nicht für alle Datentypen definiert sind...aber wenn wir schon beim Sinn von Templates sind, wie kann man den eine Template so definieren das sie z.B "nur" für Ganzzahlen kompatible ist?

    Also wie bei java mit "extends Number"



  • DKlay schrieb:

    SeppJ schrieb:

    Wenn die Klasse nur für Ganzzahltypen Sinn macht, wieso machst du dann eine Spezialisierung für eine andere Klasse? Das verbirgt doch nur den Fehler, dass die Aktion keinen Sinn macht. Das ist ein Fall für einen Compilezeitfehler, keinen Laufzeitfehler! Das finde ich ganz schlechtes Design.

    Weitere Designfehler:
    -manuelle Speicherverwaltung in einer Klasse, deren Aufgabe das nicht ist. Halte die Daten in einer auf manuelle Speicherverwaltung spezialisierten Klasse. Hier scheinen sich dafür die fertigen Standardklassen vector oder valarray anzubieten. Zumindest unter der Annahme, dass da später mal mehr als ein Wert verwaltet werden soll. Denn warum man einen Wrapper um einen einzelnen arithmetischen Wert haben sollte wäre mir total rätselhaft.
    -A propos valarray: Kann's sein, dass du gerade valarray nachprogrammierst?

    Nein das ist eine Praktikum Aufgabe, ich denke mal das soll auf evtl. auftretende Fehler hindeuten bzw. das diverse Operationen nicht für alle Datentypen definiert sind...aber wenn wir schon beim Sinn von Templates sind, wie kann man den eine Template so definieren das sie z.B "nur" für Ganzzahlen kompatible ist?

    Also wie bei java mit "extends Number"

    - duck typing, wenn man etwas mit einem typen T instanziiert wobei der typ T gewisse voraussetzungen nicht erfüllt, gibt es compilererrors.
    - enable_if: (mit vorbehalt da ich keine ahnung von c++11 habe)

    #include <type_traits>
    template<typename T>
    class VielleichtImpl
    {
    	// ...
    };
    template<typename T>
    using Vielleicht = VielleichtImpl<typename std::enable_if<std::is_integral<T>::value, T>::type>;
    

  • Mod

    DKlay schrieb:

    Nein das ist eine Praktikum Aufgabe, ich denke mal das soll auf evtl. auftretende Fehler hindeuten bzw. das diverse Operationen nicht für alle Datentypen definiert sind...aber wenn wir schon beim Sinn von Templates sind, wie kann man den eine Template so definieren das sie z.B "nur" für Ganzzahlen kompatible ist?

    So direkt leider (noch) gar nicht. Aber das ergibt sich eben ganz von alleine, da es ansonsten zu Compilerfehlern kommt, wenn der Typ nicht passt. Und wenn es doch passt, dann ist wohl alles in Ordnung, selbst wenn du von dem Typen noch nie gehört hast und beim Programmieren gar nicht an diese Möglichkeit gedacht hast (zum Beispiel meine eigene Ganzzahlklasse).

    Ich werfe auch mal boost::enable_if als Stichwort in den Raum.



  • SeppJ schrieb:

    DKlay schrieb:

    Nein das ist eine Praktikum Aufgabe, ich denke mal das soll auf evtl. auftretende Fehler hindeuten bzw. das diverse Operationen nicht für alle Datentypen definiert sind...aber wenn wir schon beim Sinn von Templates sind, wie kann man den eine Template so definieren das sie z.B "nur" für Ganzzahlen kompatible ist?

    So direkt leider (noch) gar nicht. Aber das ergibt sich eben ganz von alleine, da es ansonsten zu Compilerfehlern kommt, wenn der Typ nicht passt. Und wenn es doch passt, dann ist wohl alles in Ordnung, selbst wenn du von dem Typen noch nie gehört hast und beim Programmieren gar nicht an diese Möglichkeit gedacht hast (zum Beispiel meine eigene Ganzzahlklasse).

    Ich werfe auch mal boost::enable_if als Stichwort in den Raum.

    Naja das beste Beispiel wäre ja die max funktion, die den größten wert zurückgibt...scheitert aber an char*, da sie die Adressen vergleich und somit ja nicht zufriedenstellend arbeitet. Hier ist ja eine Spezialisierung notwendig.


  • Mod

    Ich werfe auch mal boost::enable_if als Stichwort in den Raum.

    Weil std::enable_if es nicht tut? Da braucht man nicht Boost ins Projekt einzubinden, um eine kleine Spezialisierung zu schreiben...



  • DKlay schrieb:

    SeppJ schrieb:

    DKlay schrieb:

    Nein das ist eine Praktikum Aufgabe, ich denke mal das soll auf evtl. auftretende Fehler hindeuten bzw. das diverse Operationen nicht für alle Datentypen definiert sind...aber wenn wir schon beim Sinn von Templates sind, wie kann man den eine Template so definieren das sie z.B "nur" für Ganzzahlen kompatible ist?

    So direkt leider (noch) gar nicht. Aber das ergibt sich eben ganz von alleine, da es ansonsten zu Compilerfehlern kommt, wenn der Typ nicht passt. Und wenn es doch passt, dann ist wohl alles in Ordnung, selbst wenn du von dem Typen noch nie gehört hast und beim Programmieren gar nicht an diese Möglichkeit gedacht hast (zum Beispiel meine eigene Ganzzahlklasse).

    Ich werfe auch mal boost::enable_if als Stichwort in den Raum.

    Naja das beste Beispiel wäre ja die max funktion, die den größten wert zurückgibt...scheitert aber an char*, da sie die Adressen vergleich und somit ja nicht zufriedenstellend arbeitet. Hier ist ja eine Spezialisierung notwendig.

    ich weiss, dass ich mir mit dieser aussage keine freunde mache, jedoch finde ich noch immer, dass char* oder char const* keine typen sind für zeichenketten (das wäre std::string) sondern einfach pointer-typen. std::max für std::string funktioniert hingegen auch.



  • asfdlol schrieb:

    ich weiss, dass ich mir mit dieser aussage keine freunde mache, jedoch finde ich noch immer, dass char* oder char const* keine typen sind für zeichenketten (das wäre std::string) sondern einfach pointer-typen. std::max für std::string funktioniert hingegen auch.

    std::string ist leider auch nicht der ultimative Typ für Zeichenketten. std::string bedeutet "String mit eigenem Memory-Management (und zwar pro Instanz)". Für alles andere braucht man eigene Typen. Es wird Zeit, dass es eine string_ref-Klasse gibt, die wäre dann der echte String-Typ.


Anmelden zum Antworten