Template: zweiten Parameter an Hand von erstem Ableiten



  • Hallo,

    ich habe folgende Situation:

    Es gibt eine Template-Klasse A die von B erbt

    template<typname T>
    class A : public B<T>
    

    und es gibt eine weiterre Klasse C die einen Nichttyp-Templateparameter hat

    template<unsigned int BIT>
    class C 
    {
      D<BIT> obj; 
    }
    

    Das sind vorgaben, die ich nicht ändern kann.

    Ich brauche jetzt eine neue Klasse, die beide Parameter vewenden muss

    template<unsigned int BIT, typname T>
    class F : public A<T> 
    {
      D<BIT> obj; 
    }
    

    Soweit so problemlos. Allerdings sind beide Parameter auf eine gewisse Art abhängig:
    wenn BIT 8 ist, ist es nur sinnvoll wenn T auch ein 8bit Datentyp ist.

    Gibt es da eine Möglichkeit, T "automatisch" festzulegen, sodass ich bei der Objekterzeugung nur noch
    bspw. F<8> statt F<8,uint8_t> aufrufen muss?


  • Mod

    Dafür gibt es Defaultargumente, z.B.

    template <unsigned bits> struct make_uint;
    template <> struct make_uint<8> { using type = uint8_t; };
    template <> struct make_uint<16> { using type = uint16_t; };
    template <> struct make_uint<32> { using type = uint32_t; };
    template <> struct make_uint<64> { using type = uint64_t; };
    template <unsigned bits>
    using make_uint_t = typename make_uint<bits>::type;
    //
    template<unsigned int BIT, typename T = make_uint_t<BIT>>
    class F;
    


  • Danke,

    aber das ist wohl C++11. Das kann ich leider nicht benutzen.

    Ich hab das mit typedef gemacht, aber templates und typdef werden nicht untstützt, wie ich gelesen habe. Gibt es noch einen anderen weg?

    template <unsigned bits> struct make_uint;
    template <> struct make_uint<8> { typedef uint8_t type ; };
    template <> struct make_uint<16> { typedef uint16_t type ; };
    template <> struct make_uint<32> { typedef uint32_t type ; };
    template <> struct make_uint<64> { typedef uint64_t type ; };
    template <unsigned bits>
    typedef typname typename make_uint<bits>::type make_uint_t;
    


  • template< unsigned bits > struct make_uint;
    template<> struct make_uint<  8 > { typedef uint8_t  type; };
    template<> struct make_uint< 16 > { typedef uint16_t type; };
    template<> struct make_uint< 32 > { typedef uint32_t type; };
    template<> struct make_uint< 64 > { typedef uint64_t type; };
    
    template< unsigned int BIT >
    class F
    {
    	typedef typename make_uint< BIT >::type T;
    };
    

    ?



  • Irgendwie stehe ich gerade auf dem Schlauch...

    Ich muss schon von Kasse A erben und den Templateparameter T angeben (automatisiert)

    template<unsigned int BIT, typname T>
    class F : public A<T>
    {
      D<BIT> obj;
    }
    

    Wenn ich aber in F den Typ T erst definiere, wie du schreibst:

    template< unsigned int BIT >
    class F
    {
        typedef typename make_uint< BIT >::type T;
    };
    

    dann kann ich den nicht mehr in der Basisklasse weiterreichen, oder?

    Eher sowas wie

    template< unsigned int BIT >
    class make_uint_t
    {
        typedef typename make_uint< BIT >::type TAuto;
    };
    
    template<unsigned int BIT, typname T = make_uint_t<BIT>::TAuto >
    class F : public A<T>
    {
      D<BIT> obj;
    }
    

    Aber das kompiliert nicht.



  • typename T = typename make_uint<BIT>::type
    

    muss es heißen.



  • Danke! Das so funktioniert es



  • Hm. Ich bild mir ein ich hätte es mit typename versucht. Naja, wahrscheinlich hab ichs woanders verbockt und die Fehlermeldung nicht richtig gedeutet 😕 F*cking templates ...


Anmelden zum Antworten