Verschiedene Template Instanzen in einen Container



  • Mehrere verschiedene Templateinstanzen einer Klasse in einer gemeinsamen Liste? Wer macht denn sowas? Vor allem, wie willst Du darauf zugreifen, denn die verschiedenen Instanzen haben ja unterschiedlichen Code. Mit switsch dispatchen? Nee. Es wird darauf hinauslaufen, daß die verschiedenen Templateinstanzen eine gemeinsamen Basisklasse brauchen, und Basisklassenzeiger kannste wieder mit std-Containern leicht verwalten, besser noch mit ptr-Containern.



  • Hi,

    Wie bekommen den die verschiedenen Instanzen von :

    template <typename TX,typename RX>
    class Interface{
    ...
    }
    

    eine gemeinsame Basisklasse ???
    Mit void pointern geht mir die Typensicherheit verloren...



  • Okay... 🙂 ptr container. Sorry.



  • Ich weiß tzwar nicht, welche Funktionen in Interface sind, aber nach folgendem Schema

    class BaseInterface{
    virtual void doSomething() = 0;
    virtual ~BaseInterface(); // EDIT: virtuellen Destruktor nicht vergessen
    };
    
    template <typename TX,typename RX>
    class Interface : public BaseInterface{
    ...
    virtual void doSomething(){};
    };
    

    Eventuell auch mit einem Template-Parameter.
    Kann man nach den bisherigen Infos nicht beurrteilen:

    template <typename TX>
    class BaseInterface{
    virtual void doSomething(const TX&) = 0;
    virtual ~BaseInterface(); // EDIT: virtuellen Destruktor nicht vergessen
    };
    
    template <typename TX,typename RX>
    class Interface : public BaseInterface<TX>{
    ...
    virtual void doSomething(const TX& t){};
    };
    

    Außerdem ist: Ist "Interface" wirklich passend für deine Klasse?

    Gruß,
    XSpille



  • class InterfaceBase{
       public:
          virtual ~Interface()=0;
          virtual void shoot()=0;
    };
    template <typename TX,typename RX>
    class Interface:public InterfaceBase{
        TX foo;
        RX bar;
        void shoot(){
           foo.grapelize(&bar.moo);
        }
    };
    vector<InterfaceBase*> vec;
    for each i as Interface*
       i->shoot();
    


  • 🙂
    Ja klasse



  • AlexanderKiebler schrieb:

    🙂
    Ja klasse

    Freut mich, das dieses Muster anscheinend bei Dir paßt.
    Und jetzt nur noch 999999 Programmierer, die ihre Verwendung von boost::any überdenken sollten.



  • XSpille schrieb:

    Eventuell auch mit einem Template-Parameter.
    Kann man nach den bisherigen Infos nicht beurrteilen:

    template <typename TX>
    class BaseInterface{
    virtual void doSomething(const TX&) = 0;
    

    Abgesehen davon, daß ich Template-Basisklassen mit virtuellen Funktionen noch nicht gebraucht habe, meine ich mich auch daran zu erinnern, daß das verböten ist. Oder ist das Geschichte?



  • volkard schrieb:

    AlexanderKiebler schrieb:

    🙂
    Ja klasse

    Freut mich, das dieses Muster anscheinend bei Dir paßt.
    Und jetzt nur noch 999999 Programmierer, die ihre Verwendung von boost::any überdenken sollten.

    Das Muster ist schon gut, aber manchmal exisitert keine sinnvolle gemeinsame Basisklasse. Dann sollte man auch nicht einfach irgendeine Basisklasse schreiben, nur damit die Objekte zusammen in einer Container passen.
    Gut, wenn es keine gemeinsame Basis gibt, muss man sich dann sowieso fragen, was die Objekte überhaupt in einem gemeinsamen Container zu suchen haben.

    Wann sollte man dann boost::any verwenden? Hast du gerade ein Beispiel?



  • volkard schrieb:

    XSpille schrieb:

    Eventuell auch mit einem Template-Parameter.
    Kann man nach den bisherigen Infos nicht beurrteilen:

    template <typename TX>
    class BaseInterface{
    virtual void doSomething(const TX&) = 0;
    

    Abgesehen davon, daß ich Template-Basisklassen mit virtuellen Funktionen noch nicht gebraucht habe, meine ich mich auch daran zu erinnern, daß das verböten ist. Oder ist das Geschichte?

    Das ist nicht verböten. Wenn die virtuelle Funktion selbst wieder ein Funktionstemplate wöre, dann wöre es verböten.



  • volkard schrieb:

    XSpille schrieb:

    Eventuell auch mit einem Template-Parameter.
    Kann man nach den bisherigen Infos nicht beurrteilen:

    template <typename TX>
    class BaseInterface{
    virtual void doSomething(const TX&) = 0;
    

    Abgesehen davon, daß ich Template-Basisklassen mit virtuellen Funktionen noch nicht gebraucht habe, meine ich mich auch daran zu erinnern, daß das verböten ist. Oder ist das Geschichte?

    Gut, dass du es ansprichst...
    Ich hab es bisher immer verwendet ohne damit Probleme befürchtet zu haben.
    Ich hab noch keine schlechten Erfahrungen gemacht, aber ehrlich gesagt weiß ich nicht, ob es erlaubt ist.

    Der GCC meldet mit -Wall jedenfalls keine Warnung:

    #include <string>
    
    template <typename TX>
    class BaseInterface{
    public:
    virtual void doSomething(const TX&) = 0;
    virtual ~BaseInterface(){} // EDIT: virtuellen Destruktor nicht vergessen 
    };
    
    template <typename TX,typename RX>
    class Interface : public BaseInterface<TX>{
    public:
    virtual void doSomething(const TX& t){};
    };
    
    int main(){
            BaseInterface<std::string>* i = new Interface<std::string, int>();
            i->doSomething("");
    }
    


  • Mitleid schrieb:

    volkard schrieb:

    XSpille schrieb:

    Eventuell auch mit einem Template-Parameter.
    Kann man nach den bisherigen Infos nicht beurrteilen:

    template <typename TX>
    class BaseInterface{
    virtual void doSomething(const TX&) = 0;
    

    Abgesehen davon, daß ich Template-Basisklassen mit virtuellen Funktionen noch nicht gebraucht habe, meine ich mich auch daran zu erinnern, daß das verböten ist. Oder ist das Geschichte?

    Das ist nicht verböten. Wenn die virtuelle Funktion selbst wieder ein Funktionstemplate wöre, dann wöre es verböten.

    Dann bin ich beruhigt 👍



  • Mitleid schrieb:

    Das ist nicht verböten. Wenn die virtuelle Funktion selbst wieder ein Funktionstemplate wöre, dann wöre es verböten.

    Jupp, das hab ich verwechselt.



  • icarus2 schrieb:

    volkard schrieb:

    AlexanderKiebler schrieb:

    🙂
    Ja klasse

    Freut mich, das dieses Muster anscheinend bei Dir paßt.
    Und jetzt nur noch 999999 Programmierer, die ihre Verwendung von boost::any überdenken sollten.

    Das Muster ist schon gut, aber manchmal exisitert keine sinnvolle gemeinsame Basisklasse. Dann sollte man auch nicht einfach irgendeine Basisklasse schreiben, nur damit die Objekte zusammen in einer Container passen.
    Gut, wenn es keine gemeinsame Basis gibt, muss man sich dann sowieso fragen, was die Objekte überhaupt in einem gemeinsamen Container zu suchen haben.

    Wann sollte man dann boost::any verwenden? Hast du gerade ein Beispiel?

    Ich habe es noch nie gebraucht.
    Muß aber fast täglich lesen, wie gut es sei: http://www.c-plusplus.net/forum/284902



  • volkard schrieb:

    icarus2 schrieb:

    volkard schrieb:

    AlexanderKiebler schrieb:

    🙂
    Ja klasse

    Freut mich, das dieses Muster anscheinend bei Dir paßt.
    Und jetzt nur noch 999999 Programmierer, die ihre Verwendung von boost::any überdenken sollten.

    Das Muster ist schon gut, aber manchmal exisitert keine sinnvolle gemeinsame Basisklasse. Dann sollte man auch nicht einfach irgendeine Basisklasse schreiben, nur damit die Objekte zusammen in einer Container passen.
    Gut, wenn es keine gemeinsame Basis gibt, muss man sich dann sowieso fragen, was die Objekte überhaupt in einem gemeinsamen Container zu suchen haben.

    Wann sollte man dann boost::any verwenden? Hast du gerade ein Beispiel?

    Ich habe es noch nie gebraucht.
    Muß aber fast täglich lesen, wie gut es sei: http://www.c-plusplus.net/forum/284902

    Immer noch besser als void*, auch wenn ich selbst keinen Anwendungsfall kenne 😉



  • Gibts ne Möglichkeit dadraus wieder zu lesen ???..
    Also das Problem ist wenn ich im Interface eine lese Methode schreibe,
    weiß ich nicht welchen typ ich zurückgeben soll.



  • Das ist das Problem bei der Methode. Bei Zeigern auf die Basisklasse kann man wenigstens noch über virtuelle Funktionen was hinbekommen, bei boost::any gibt es keine Möglichkeit, das muss der Programmierer wissen.
    Evtl liese sich da auch noch was mit einem static dispatcher machen. Aber performancetechnisch ist das ziemlich fragwürdig.


Anmelden zum Antworten