Template Typedef - oder wie definiere ich nur die Hälfte von Template Parametern ??



  • Hi Leute

    Hab grad ne Wissenslücke, und bevor ich mir nen Wolf schreib..

    Also ich möchte von streambuf erben, im Header <streambuf> find ich dann folgendes:

    namespace std {
    template<class Elem, class Tr = char_traits<Elem> >
        class basic_streambuf;
    typedef basic_streambuf<char, char_traits<char> >
        streambuf;
    typedef basic_streambuf<wchar_t,
        char_traits<wchar_t> > wstreambuf;
    }  // namespace std
    
    template <class Elem, class Tr = char_traits<Elem> >
        class basic_streambuf {
    public:
        typedef Elem char_type;
        typedef Tr traits_type;
        typedef typename traits_type::int_type int_type;
        typedef typename traits_type::pos_type pos_type;
        typedef typename traits_type::off_type off_type;
    
    //und dann der ganze Klassenrumpf;
    

    Nun wollt ich meine eigene streambuf Klasse auch flexibel halten und möglichst mit verschiedenen Widgets instanzieren. Meine Idee drum:

    template< typename WidgetT,
            typename charT,typename Tr = char_traits<charT> >
    class Qt_basic_streambuf;
    

    Und für Widgets, die dann zB keine setText Methode haben spezialisieren. Aber wie mach ich nun die typedefs für char und wchar_t Unterscheidung?

    template< typename WidgetT, typename charT,
                  typename Tr = char_traits<charT> >
        class Qt_basic_streambuf;
        typedef Qt_basic_streambuf< ???, char,    char_traits<char> >    Qt_streambuf;
        typedef Qt_basic_streambuf< ???, wchar_t, char_traits<wchar_t> > Qt_wstreambuf;
    

    Ehrlich gesagt weiss ich gar nicht viel über Qt und wide chars, und ob das so überhaupt nötig ist?

    Btw: An die Experten, die char_traits könnte man doch mit template template parametern instanzieren oder?

    Danke im voraus
    🙂



  • Ach ja, wieso ich das brauch.
    Die Rückgabewerte der overflow und sync Methoden sind traits_type::int_type, das hat wohl geändert im Vergleich zu Beispielen im Netz.



  • Ich sags nur ungern, aber es gibt keine template-typedefs.



  • Mist, dacht ichs mir doch.
    Und jetzt? Wie kann ich das trotzdem hinkriegen?



  • Entweder warten, bis C++0x kommt (keine gute Idee, wohl zu zeitintensiv ;)) oder durch ableiten und gegebenenfalls Konstruktoren "weiterleiten":

    template <typename WidgetT>
    class Qt_streambuf : public Qt_basic_streambuf<WidgetT, char>
    {
    public:
        // Beispiel:
        Qt_streambuf (int i) : Qt_basic_streambuf<WidgetT, char> (i)
        {}
        // ... entsprechend die anderen nichttrivialen Konstruktoren
    };
    
    // und das gleiche nochmal für Qt_wstreambuf
    


  • Danke, das wird wohl gehen 👍



  • .filmor schrieb:

    Entweder warten, bis C++0x kommt (keine gute Idee, wohl zu zeitintensiv ;)) oder durch ableiten und gegebenenfalls Konstruktoren "weiterleiten":

    Oder mit einer Metafunktion:

    template <typename WidgetT>
    struct Qt_streambuf {
        typedef typename Qt_basic_streambuf<WidgetT, char> result;
    };
    
    // und "instanzieren" per:
    
    typedef Qt_streambuf<QtButton>::result MyQtStreambufButton;
    


  • Aber die Vererbungsvariante kann man später, wenn das neue C++ fertig ist, durch using ersetzen ;). Trotzdem schön, werd ich mir merken.



  • Hey Konrad, sehr schön danke.

    Da hier ja grad die Experten anwesend sind wollt ich die Frage nochmal aufgreifen

    ich schrieb:

    ..die char_traits könnte man doch mit template template parametern instanzieren oder?

    In etwa so?

    template< typename WidgetT,
            typename charT, template <typename> class char_traits >
    class Qt_basic_streambuf
    {
    ...
    

    Sorry für die seltsamen Fragen, ich versuch grad die "höheren Ebenen" von C++ zu verstehen 🙂



  • Hi Kathi,

    ich verstehe nicht ganz, was Du damit meinst. Die char_traits sind doch bereits mit Template-Parametern instanziert.



  • Aber es ist ja noch möglich zu schreiben:

    basic_streambuf< char, char_traits<wchar_t> > mixedmodestreambuf;
    

    Und das wird wohl ziemlich seltsame Ergebnisse liefern.

    Ok, blödes Beispiel, aber ich mein vom Prinzip her.



  • Okay, um das Problem zu lösen brauchst Du Concepts, => d.h. Warten, bis C++0x herauskommt.

    Ansonsten kann man diesen Parameter evtl. auch einfach vollkommen weglassen.

    template <typename CharT> basic_streambuf {
        typedef typenameme char_traits<CharT> char_traits;
        // ...
    };
    


  • Concepts... jetzt habt ihr meine Neugier auf C++0x geweckt 😋 (ist das 0x eigentlich für hex?)
    Was ich meinte war sowas: http://www.progdoc.de/papers/ttp/psi-ttp/psi-ttp.html
    Ist wohl nicht so bekannt, weils MSVC lange nicht unterstützt hat.

    Naja, auf jedenfall besten Dank, mein stream funktioniert jetzt. 🙂



  • Conceptchecking gibts auch schon in C++, siehe http://www.boost.org/libs/concept_check/concept_check.htm.

    C++0x steht für ein Erscheinen vor 2010 ... ziemlich optimistisch 😉

    Natürlich könntest du Template-Templateparameter verwenden, aber dann kannst du nur noch Templates als Traits benutzen (was nicht immer praktisch ist).



  • Ahja boost hat da was? cool. Heisst das bei erscheinen des 0x Standards müsst ich nur die Namespace Prefixes ändern? Das wär ja was. 🕶

    btw:
    Woher wisst ihr das alles eigentlich? Lernt man das in der Ausbildung (Studium?) oder in Seminaren oder habt ihr das alles aus Büchern zusammen gelesen?
    Ich kratz mir das so aus allen möglichen Artikeln und Newsgroups zusammen, bin halt Autodidaktin, aber es ist schwierig zu verstehen wann was praktisch ist.



  • kathi89 schrieb:

    Ahja boost hat da was? cool. Heisst das bei erscheinen des 0x Standards müsst ich nur die Namespace Prefixes ändern? Das wär ja was. 🕶

    AFAIK wird concept-checking in C++0x Compiler-seitig unterstützt. Ich denke, das schaut dann etwas anders aus. Aber ich bin mir ziemlich sicher, dass die Boost-Leute da wieder wrappen, was nur geht (so wie auch bei Boost.Typeof).

    kathi89 schrieb:

    btw:
    Woher wisst ihr das alles eigentlich? Lernt man das in der Ausbildung (Studium?) oder in Seminaren oder habt ihr das alles aus Büchern zusammen gelesen?
    Ich kratz mir das so aus allen möglichen Artikeln und Newsgroups zusammen, bin halt Autodidaktin, aber es ist schwierig zu verstehen wann was praktisch ist.

    Ein paar gute Bücher als Grundlage und ansonsten auch was man so liest plus etwas Praxis. Also in meinem Studium (das ich erst zu diesem Wintersemester angefangen habe) lern ich sowas nicht.



  • Ok, danke euch.
    Dann ist es wohl die fehlende Praxis die mir fehlt (was fürn Satz 🤡 )
    Ich frag dann einfach ab und zu bei euch hilfsbereiten Experten nach 🙂

    Bye



  • Konrad Rudolph schrieb:

    Oder mit einer Metafunktion:

    template <typename WidgetT>
    struct Qt_streambuf {
        typedef typename Qt_basic_streambuf<WidgetT, char> result;
    };
    

    Das typename gehört dort allerdings nicht hin.



  • groovemaster schrieb:

    Konrad Rudolph schrieb:

    Oder mit einer Metafunktion:

    template <typename WidgetT>
    struct Qt_streambuf {
        typedef typename Qt_basic_streambuf<WidgetT, char> result;
    };
    

    Das typename gehört dort allerdings nicht hin.

    Ja, stimmt natürlich.


Anmelden zum Antworten