Template-Spez. soll von allg. Template abgeleitet sein...



  • Moin,
    Ich versuche dem Compiler klar zu machen, dass eine Template-Spezialisierung eine Ableitung des allgemeinen Templates sein soll.

    Hier der Code:

    template<int I> class D{};
    template<int J> class D<123> : D<J>{};
    

    Entweder beschwert er sich, dass ich J nicht nutze, oder, falls ich J als Parameter weg lasse, dass er nicht weiß was J ist.
    Den 2ten Fall kann ich noch nachvollziehen, aber warum er glaubt, ich würde J nicht nutzen verstehe ich nicht.

    Hat jemand einen Vorschlag, wie das gehen könnte?

    Gruß,
    0xMöbius!



  • Sowas WÜRDE gehen:

    template <int I>
    class A {};
    
    template <>
    class A <1> : public A <0>
    {
    };
    

    Und sowas ergibt keinen Sinn: (Bedenke, was wenn J = 1? ⚠ )

    template <int I>
    class A {};
    
    template <int J>
    class A <1> : public A <J>
    {
    };
    

    Außerdem finde ich es außerordentlich bedenklich, dass du eine Klasse quasi von sich selbst ableiten lässt.

    EDIT: ob private oder public Vererbung ist ja grundsätzlich hier erstmal egal.



  • Ich glaube so wie du dir das vorstellst geht es gar nicht. Man muss sich doch nur mal überlegen was passieren soll wenn man D<654> schreibt. Soll dann dann die "normale" D<654> Klasse genommen werden oder D<123> welche von D<654> erbt? Beides hat einen Template Parameter. Deine Hauptklasse müsste schon zwei Template Parameter haben und deine Spezialisierung nur eine. Sowas z.B.

    template<int I, int J = 0> class D {};
    template<int J> class D<123, J> : D<J>{};
    

    Wobei mir noch nicht klar ist was du mit der Vererbung erreichen willst.



  • Danke schonmal für eure Antworten!
    Also ich habe mir dabei gedacht, dass ich, nur falls der Template-Parameter I = 123 ist, vom allgemeinen Fall ableiten möchte. Und für jeden anderen Wert eben den allgemeinen Fall ohne Ableitung nehmen möchte.
    Kann man da vielleicht irgendwas mit template-templates machen?

    @5cript:

    Und sowas ergibt keinen Sinn: (Bedenke, was wenn J = 1? ⚠ )

    Ooohhh.... 😮

    Außerdem finde ich es außerordentlich bedenklich, dass du eine Klasse quasi von sich selbst ableiten lässt.

    Mal ne ernst gemeinte Frage: Ich dachte Klassen von Klassen-Templates sind genau genommen total verschieden (Mal den Fall J = 1 ausgenommen). Stimmt doch, oder?!
    Das war aber eh nur dazu gedacht, das Bsp minimal zu halten. Also, wie wärs damit:

    template<int I> class D{};
    template<int I> class E{};
    template<int I> class E<0> : D<I>{};
    

    Das müsste doch alle deine Bedenken ausräumen...

    @sebi707:

    Man muss sich doch nur mal überlegen was passieren soll wenn man D<654> schreibt. Soll dann dann die "normale" D<654> Klasse genommen werden oder D<123> welche von D<654> erbt?

    Also nach meiner persönlichen "Logik" (s.o.) sollte die normale genommen werden...

    Deine Hauptklasse müsste schon zwei Template Parameter haben und deine Spezialisierung nur eine. Sowas z.B.

    Hmm, das muss ich mir erst nochmal durch den Kopf gehen lassen.. Du meinst quasi eine Art Dummy-Parameter?!

    Wobei mir noch nicht klar ist was du mit der Vererbung erreichen willst.

    Mir so ganz auch nicht. Eigentlich wollte ich nur rausfinden, was so möglich ist.. ..z.B. um mir einiges an copy&paste ersparen zu können.



  • 0xMöbius schrieb:

    Außerdem finde ich es außerordentlich bedenklich, dass du eine Klasse quasi von sich selbst ableiten lässt.

    Mal ne ernst gemeinte Frage: Ich dachte Klassen von Klassen-Templates sind genau genommen total verschieden (Mal den Fall J = 1 ausgenommen). Stimmt doch, oder?!

    Das war aber eh nur dazu gedacht, das Bsp minimal zu halten. Also, wie wärs damit:

    template<int I> class D{};
    template<int I> class E{};
    template<int I> class E<0> : D<I>{};
    

    Das müsste doch alle deine Bedenken ausräumen...

    1. Ja
    2. Da könnte ich viel besser schlafen 🙂

    Ich denke jedoch, dass deine ursprüngliche Idee leicht zu Verwirrung führen könnte. Da ich mich bei Vererbung immernoch an Meyers (EffectiveC++) halte ("ist ein" und "ist implementiert in Form von"), bin ich darauf gepolt Vererbung nicht zu stark zu missbrauchen.

    EDIT: Konstrukte haben für mich oft genauso viel Bedeutung wie Namen.

    Vielleicht haben Andere ja etwas anderes dazu zu sagen.



  • 0xMöbius schrieb:

    sebi707 schrieb:

    Man muss sich doch nur mal überlegen was passieren soll wenn man D<654> schreibt. Soll dann dann die "normale" D<654> Klasse genommen werden oder D<123> welche von D<654> erbt?

    Also nach meiner persönlichen "Logik" (s.o.) sollte die normale genommen werden...

    OK andere Frage. Wie willst du dann den J Template Parameter festlegen?



    1. Da könnte ich viel besser schlafen 🙂

    Ich leider nicht. Denn zumindest mit dem gcc geht das auch nicht..
    Aber ich habe jetzt, denke ich verstanden was los ist:

    OK andere Frage. Wie willst du dann den J Template Parameter festlegen?

    Gute Frage..;) Ich hatte gehofft, dass der Compiler quasi eine Ersetzung macht. Wenn er also zB. ".. : xy<int I, typename T>{};" sieht, und irgendwo anders eben dieses "xy<int I, typename T>{};" existiert, er es einfach ersetzt. Tja falsch gedacht. Msvc scheint sowas zu machen, oder gemacht zu haben. Ich habe irgendwo gelesen, dass es funktioniert hat. Ich nutze aber nur den gcc.. Von daher 🕶

    MfG
    0xMöbius



  • 0xMöbius schrieb:

    1. Da könnte ich viel besser schlafen 🙂

    Ich leider nicht. Denn zumindest mit dem gcc geht das auch nicht..

    Oh ja das habe ich gar nicht mehr ausprobiert.
    Wenn ich drüber nachdenke und es "behebe" findet sich die Information zur Ableitung schon in der nicht spezialisierten Klasse wieder (als Template Parameter).
    => Erste Antwort von sebi707



  • Hast du das eigentlich schonmal so betrachtet?:

    template <typename T>
    struct B
    {
        /* EBCO */
    };
    
    template <>
    struct B <int>
    {
        int f();
        // ... more ...
        // Ersetzt Spezialisierung von C
    };
    
    template <typename T>
    struct C : public B <T>
    {
    };
    

    Es ist nicht genau das gleiche, aber je nach Anwendungsfall könnte man dies als Alternative wählen.
    Ich sehe aber immernoch keinen sinnvollen Use Case...



  • Hast du das eigentlich schonmal so betrachtet?:

    Habe ich tatsächlich.. 💡
    Aber wegen der ganzen Operatore (+Ctor/Dtor) wollte ich eher die abgeleitete Klasse spezialisieren.
    Ist es hier möglich direkt die OPs der Basisklasse zu nutzen??
    Irgendwas mit "using" vielleicht?
    Und was ist z.B. mit dem Ctor/Dtor, oder dem Cast-OP?

    Ich habe keine Ahnung, wie das gehen könnte...

    Ich sehe aber immernoch keinen sinnvollen Use Case...

    Der kommt vielleicht später, wenn ich weiß, was ich überhaupt mache. Evtl., um es mit deinen Worten zu sagen, ein "zu starker Missbrauch von Vererbung". 😃


Anmelden zum Antworten