//template myclass< typname VectorClass > ... typ der TemplateClass ermittlen



  • muffmolch schrieb:

    ganz einfach:
    ...

    Hast du dir mal die Typedefs innerhalb von std::vector angeschaut?

    Probiere mal:
    VectorClass::value_type als Typangabe

    Der Trick ist folgender (Unvollständiges Minibeispiel):

    template<typename T>
    class T1
    {
        public:
            typedef T value_type;
            ...
    };
    
    template<typename T1Type>
    class T2
    {
        private:
            T1Type::value_type var;  // Verwendet das Typedef "value_type"
            ...
    };
    

    cu André



  • ja, das ist die beste lösung.
    klappt 1A. ärgerlich, das sich da nicht selbst drauf gekommen bin



  • Traits ist afaik etwas anderes (taucht aber auch gelegentlich in der STL auf - besonders wenn man dem Typ keine zusätzlichen Typedefs aufquetschen kann).

    muffmolch schrieb:

    d.h., bei einem eigenen datentyp mus sich lediglich so ein typedef definieren, ja?

    Ja, solange du die Möglichkeit dafür hast:

    template<typename T>
    class ToVector
    {
    public:
      typedef T value_type;
      ...
    };
    

    Wenn du die ToVector-Klasse nicht verändern kannst/willst, kannst du auch eine Traits-Klasse als Hilfsmittel verwenden:

    template<typename Cont>
    struct container_traits
    {
      typedef typename Cont::value_type value_type;
      ...//die STL-Container bieten noch einige weitere hilfreiche typedef's
    };
    
    template<typename T>
    struct container_traits<ToVector<T> >
    {
      typedef T value_type;
      ...
    };
    
    //Verwendung
    template<typename VectorClass>
    class MyClass
    {
      MyClass()
      {
        typename container_traits<VectorClass>::value_type temp;
        ...
      }
      ...
    };
    


  • Ich sags mal mti deinem Beispiel:

    template< typename VectorClass >
    class MyClass
    {
      typedef VectorClass::value_type value_type; //die Ts aus den vectorklassen
    
      MyClass()
      {
      }
    };
    
    int main()
    {
       MyClass< vector<int> >     a1; //hier wäre value_type=int
       MyClass< vector<float> >   a2; //hier wäre value_type=float
       MyClass< ToVector<int> >   a3; //hier wäre value_type=int
       MyClass< ToVector<float> > a4; //hier wäre value_type=float
    
       return 0;
    };
    

    Das Design setzt voraus, dass jegliche mit diesem Template verwendete vector-Klasse ein typedef namens value_type bereitstellt (moeglichst auf ihren "T-Typ"):

    template <typename T>
    class ToVector {
      typedef T value_type; //<<wichtig
    };
    

    Ist sowieso immer nett, wenn man bei eigenen Containerklassen derartige typedefs mitliefert, um sie so weit wie moeglich mit den std::Containern kompatibel zu halten.



  • wie ist denn das mit typedefs und vererbung?

    class A{
    public: 
      typedef int value_type;
    };
    
    class B : public A{
    public: 
      typedef float value_type;
    };
    


  • muffmolch schrieb:

    kann man das nur mit einem zweiten template argument erschlagen, also

    template< typename VectorClass, typename T >
    class MyClass
    

    und wenn, kann man dann irgendwie garantieren, dass man nicht:

    MyClass< vector<float>, int > a1;
    

    angeben kann???

    man kann. mit dem c++ template-template-feature:

    template<template <typename> class TC, typename TV>
    class foo
    {
    public:
        typedef TV value_type;
        //...
    private:
        TC<value_type> m_bar;
    };
    
    int main()
    {
        foo<std::vector, int> f;
    }
    


  • template-template schrieb:

    man kann. mit dem c++ template-template-feature:

    Ja, darüber hatte ich auch nachgedacht, es aber verworfen, weil die Lösung hier nicht funktionieren wird (auch wenn das kaum ein Programmierer bemerkt, benötigt std::vector ZWEI Template-Parameter und ist deshalb nicht kompatibel zur MyClass-Parameterliste).



  • oh. gehen default template-parameter laut standard nicht mit template-template-parametern? mit mingw-gcc-3.4.5 kompiliert es gut. habs jetzt mit vc-7.1 probiert und der will tatsächlich nicht.


  • Mod

    muffmolch schrieb:

    d.h., bei einem eigenen datentyp mus sich lediglich so ein typedef definieren, ja?

    Auch eine Templatemetafunktion kann prinzipiell dafür genutzt werden - das Wort traits würde ich dafür aber nicht unbedingt verwenden:

    template< typename VectorClass >
    class MyClass;
    
    template< typename T >
    class TemplateTypeParameter1of1 {};
    
    template< template< typename > class T, typename U >
    class TemplateTypeParameter1of1< T< U > >
    {
        typedef U type;
    };
    

    über TemplateTypeParameter1of1< C >::type ist dann der Templateparameter ermittelbar, selbst wenn C kein inneres typedef dafür hat.



  • template-template schrieb:

    oh. gehen default template-parameter laut standard nicht mit template-template-parametern? mit mingw-gcc-3.4.5 kompiliert es gut. habs jetzt mit vc-7.1 probiert und der will tatsächlich nicht.

    Nein, geht laut standard nicht. Und selbst wenn man es auf irgendeine getrickste Weise hinbekommt, im Falle eines std::vector<>s noch den Allocator dazuzufrickeln, ist dem Library-Hersteller nicht verboten, im vector<> noch eigene zusaetzliche Templateparameter (mit defaults) einzubauen die alles wieder ueber den Haufen schiessen. Deshalb sind std::Container allgemein nicht geeignet fuer template template parameter 😞


  • Mod

    nt



  • nt?



  • no text

    scnr



  • template-template schrieb:

    oh. gehen default template-parameter laut standard nicht mit template-template-parametern? mit mingw-gcc-3.4.5 kompiliert es gut. habs jetzt mit vc-7.1 probiert und der will tatsächlich nicht.

    schoen zu sehen, dass minGW alias gcc mal etwas durchläßt und der doch sehr liberal eingestellte cl-compiler nicht 🙂


Anmelden zum Antworten