Template-Ableitungsproblem



  • Hallo,

    ich habe ein kleines Denkproblemchen. Ich poste einfach erstmal den Code. Es geht
    hier primär um die Hierarchie und das Design; nicht um den Inhalt.

    #ifdef MSC_VER
    #	define NOVTABLE	__declspec(novtable)
    #	define ABSTRACT abstract
    #else
    	#define NOVTABLE
    	#define ABSTRACT
    #endif
    
    template<
    	class  Ty,
    	size_t n
    >
    struct NOVTABLE Member ABSTRACT
    {
    protected:
    	enum {Elem = n};
    	mutable Ty memb[n];
    };
    
    template<
    	class Ty,
    >
    struct NOVTABLE Member<Ty, 0> ABSTRACT
    {
    protected:
    	size_t Elem;
    	mutable Ty* memb;
    };
    
    template<
    	class Ty
    >
    class NOVTABLE Interface ABSTRACT
    {
    protected:
    	enum {elSize = sizeof(Ty)};
    
    public:
    	virtual func1() = 0;
    	virtual func2() = 0;
    	virtual func3() = 0;
    };
    
    template<
    	class  Ty,
    	size_t n,
    	typename SPECIAL_FUNC<_Ty>::FUNCTION* func = NULL
    >
    class NOVTABLE Implementation ABSTRACT
    	: public Member<Ty, n>,
    	  public Interface<Ty>,
    	  public Mehr<Ty, n, func>
    {
    public:
    	virtual func1() {}
    	virtual func2() {}
    	virtual func3() {}
    };
    
    template<
    	class  Ty,
    	size_t n,
    	typename SPECIAL_FUNC<_Ty>::FUNCTION* func = NULL,
    	typename Allocator = BAlloc<Ty>
    >
    class FirstUse : public  Implementation<Ty, n, func>,
    				 private Allocator
    {
    	[...]
    };
    

    Jetzt soll an folgende Klasse ein Typ der sich an "Interface" orientiert
    übergeben werden. Es soll eine Instanz dieses Tps gebildet werden können.
    Mein Problem ist jedoch, dass Interface allein nur die halbe Miete ist.
    Es soll natürlich die Möglichkeit bestehen z.B. "FirstUse" zu verwenden.
    Aber wie? Da fehlen dann ja Parameter?

    template<
    	class  Ty,
    	size_t n, 
    	class  Interface = Interface<Ty>
    >
    class Class
    {
    	[...]
    };
    

    Hat da jemand vielleicht einen netten Vorschlag?



  • Es ist erstmal völlig unklar was du da versuchst zu tun. Das hast du scheinbar vergessen zu erwähnen. Und welche Parameter meinst du fehlen da? Es wird nicht wirklich klar was du machen möchtest.
    Gib uns am Besten nochmal den allernötigsten Code den du hast. Nicht mehr, weil mehr einfach nur verwirrt. Den MSVC-Spezialkram kannst du auch erstmal weglassen, der verkompliziert das Verständnis unnötig. Und nimm am Besten den Code den du selbst dort hast, der hier scheint irgendwie zusammenkopiert zu sein, da sind überflüssige Kommata, teils _Ty, teils Ty, und erkläre was du erreichen möchtest mit dem jeweiligen Code.
    Mit dem was du uns da vorgelegt hast ist nicht klar was das alles überhaupt soll.



  • template<
    	class  Ty,
    	size_t n
    >
    struct Member
    {
    protected:
    	enum {Elem = n};
    	mutable Ty memb[n];
    };
    
    template<
    	class Ty,
    >
    struct Member<Ty, 0> 
    {
    protected:
    	size_t Elem;
    	mutable Ty* memb;
    };
    
    template<
    	class Ty
    >
    class Interface
    {
    protected:
    	enum {elSize = sizeof(Ty)};
    
    public:
    	virtual func1() = 0;
    	virtual func2() = 0;
    	virtual func3() = 0;
    };
    
    template<
    	class  Ty,
    	size_t n,
    	typename SPECIAL_FUNC<Ty>::FUNCTION* func = NULL
    >
    class Implementation 
    	: public Member<Ty, n>,
    	  public Interface<Ty>,
    	  public Mehr<Ty, n, func>
    {
    public:
    	virtual func1() {}
    	virtual func2() {}
    	virtual func3() {}
    };
    
    template<
    	class  Ty,
    	size_t n,
    	typename SPECIAL_FUNC<_Ty>::FUNCTION* func = NULL,
    	typename Allocator = BAlloc<Ty>
    >
    class FirstUse : public  Implementation<Ty, n, func>,
    				 private Allocator
    {
    	[...]
    };
    

    Also,
    ich habe ein Interface für eine spezielle Klasse deklariert. Alle Ableitungen dieser Klasse verfügen also
    über die Methoden dieser Schnittstelle.
    Es gibt jedoch eine Unterscheidung zwischen den Membern (der Zugriff bleibt aber gleich).

    Die Implementation Klasse implementiert die zuvor virtuelle Methoden. "FirstUse" ist die erste
    instanzierbare Klasse, welche von Implementation ableitet.

    So, dass ist alles wunderbar. Jetzt möchte ich jedoch eine weitere Template-Klasse erschaffen, die eben jene
    Klasse oben als Member erhält. Die Frage ist jetzt bei mir, wie ich das machen soll?

    Ich könnte beispielsweiße folgendes "verlangen":

    template<
    	class Ty
    	class MemberTyp = Interface<Ty>
    >
    class Class
    {
    private:
    	MemberTyp<Ty> Memb;
    }
    

    So, dann würde ich implizit einen Typ erwarten, der sich an Interface orientiert. Mein Problem ist aber, dass auf diese
    Art die Klasse "FirstUse" nicht als "MemberTyp" möglich wäre; soll es aber.

    Mein Problem ist ganz einfach, dass sich die erste echte Ableitung von Interface (FirstUse) nicht an deren TemplateParameter
    hält, sondern mehr hat.

    Vielleicht sollte ich das Interface einfach auf dide Parameter von FirstUse abwandeln, ich hatte aber eigentlich geplant
    mehrere Ableitung a la FirstUse zu haben, die durchaus weitere Template-Parameter haben. Die halten sich aber alle an die
    Konventionen von Interface.

    mmh, ich hoffe dass es jetzt etwas verständlicher wird 😉



  • Suchst du sowas?

    template < typename Tx >
    struct Base
    {
        Tx x;
    };
    
    template < typename Tx, typename Ty>
    struct Derived : public Base<Tx>
    {
        Ty y;
    };
    
    template < typename Bx, typename T = Base<Bx> >
    struct Aggregate
    {
        T mem;
    };
    
    int main()
    {
        Aggregate<int> agg1;
        Aggregate<int, Derived<int, int> > agg2;
    }
    


  • Okay, vergesst es Jungs 😉
    Eine Woche Schweinegrippe hat mir also doch geschadet ...


Anmelden zum Antworten