Spezialisierung von Template-Klassen



  • Hallo,

    unserer Prof hat gemeint, dass es nur die Wege gibt, eine Template-Klasse zu spezialisieren

    1. globale Template-Funktionen schreiben, diese spezialisieren und aus den Klassenmethoden heraus delegieren

    2. eine Klasse von einer Template-Klasse ableiten und die speziellen Methoden überschreiben

    3. die gesamte Klasse kopieren und die Typvariablen durch den speziellen Typ ersetzen

    Beides ist nicht wirklich toll zu machen. Gibt es da keine andere Möglichkeit? Die Spezialisierung direkt in die Klasse unter die Methode zu schreiben, wäre wohl ideal, aber das geht laut Prof ja nicht.

    Danke,
    Thilo



  • Thilo87 schrieb:

    1. ...

    2. ...

    3. ...

    Beides ist nicht wirklich toll zu machen.

    Nett 😃

    Gib mal Codebeispiele dazu, was das genau meint.

    Z.B. die dritte Möglichkeit kommt in der freien Wildbahn nur extrem selten vor, jedenfalls bei komplexen Klassen (Beispiel std::vector<bool>)



  • 4.) SFINAE

    Damit hätten wir schon drei Sachen 😃

    (falls ich überhaupt verstanden habe was er meint)



  • Ja, die dritte Möglichkeit war mir erst später eingefallen, nachdem ich schon "Beide" geschrieben hatte 😉

    Also ich meine, man hat eine Template-Klasse und in dieser eine Methode

    template <typename T>
    class Klasse
    {
    ...
    
    public:
    ...
    
    T gibWas () const
    {
       T was( 1, 2 ) ;
       T.irgendwas( 3 ) ;
    
       return was ;
    }
    
    }
    

    Jetzt ist es so, dass für ein spezielles T, z.B. T == string, statt

    T was( 1, 2 ) ;
        T.irgendwas( 3 ) ;
    

    das hier aufgerufen werden muss

    T was( 1, 2 ) ;
        T.irgendwasanderes ( 3 ) ;
    

    Es ist nur diese eine Methode, die speziell für T == string eine andere, spezielle Semantik braucht. Für die restlichen unendlich vielen T gilt die originale Semantik.
    Da bleiben einem jetzt laut Prof die obigen drei Möglichkeiten, die aber eben alle nicht so toll sind.

    Gibt es da eventuell doch noch bessere Möglichkeiten?



  • Ja, kein Problem: Templatemethodenspezialisierung.

    template <>
    std::string Klasse<std::string>::gibWas() const
    {
      std::string was( 1, 2 ) ;
      std::string().irgendwasanderes ( 3 ) ;	
    }
    


  • Und wenn du einen Comnpilererror willst, falls irgendwer versucht deine default-Template zu verwenden kannst du das so machen:

    template<typename T> T func() {T::undefined_function_call(); return T();}
    template<> int func() {/* do your thing */}
    


  • Oder seit C++11 template<typename T> T func() = delete;



  • Nathan schrieb:

    Oder seit C++11 template<typename T> T func() = delete;

    Hah!
    Det kannte ich noch gar nicht. Cool 🙂



  • hustbaer schrieb:

    Nathan schrieb:

    Oder seit C++11 template<typename T> T func() = delete;

    Hah!
    Det kannte ich noch gar nicht. Cool 🙂

    Ich musst es nach dem Schreiben auch erst mal durch ideone jagen, um zu gucken obs überhaupt geht. 😃


Log in to reply