generische C-Programmierung



  • Hallo Leute,

    ich suche eine elegante Lösung für folgendes Problem:
    Angenommen man hat zwei Code-Stücke vorliegen, die jeweils durch Ersetzung einer Zeichenkette ineinander überführt werden können, z.B. (in Pseudo-Code):

    // erstes Code-Stück
    hund_lauf();
    hund_belle();
    hung_spring;
    /* ... */
    
    // zweites Code-Stück
    katze_lauf();
    katze_belle();
    katze_spring;
    /* ... */
    

    Hier ergibt sich z.B. Code-Stück zwei aus Code-Stück eins indem man textuell "hund" durch "katze" ersetzt.

    Gibt es in C/C++ eine elegante Möglichkeit solch einen Code lediglich einmal zu schreiben und dann für "hund" oder "katze" zu "instanziieren" (um so Code-Stück 1 und Code-Stück 2, wie oben dargestellt, zu erhalten)?

    Ich erhoffe mir durch ein eleganteres vorgehen Redundanzen zu vermeiden und müsste Änderungen am Code nicht stets simultan an beiden Code-Stücken vornehmen.

    Danke im Voraus.



  • Funktionszeiger?



  • //benutzer:
    #define TIER katze
    #include "tier.h"
    #undef tier
    
    //"templates" in tier.h:
    tier##_lauf();
    tier##_belle();
    tier##_spring;
    

    Falls es soweit gehen soll, die stl zu simulieren, ist das Vorhaben aber Unfug. Wirst immer wieder Ärger bekommen und irgendwann entnervt aufgeben als der zenhtausendste Versucher. Ich hatte damit selber schonmal angefangen und hab nach mir Leuten zugeschaut.

    Mal diesen oder jenen speziellen Code generisch zu machen, das geht.



  • Vielen Dank für die Antworten.

    @volkard:
    Deine Idee ist super, nur entfernt der Präprozessor nicht die "##" und ich bekomme einen Compiler-Error. Weißt du was ich falsch mache?

    Danke



  • Gast12345 schrieb:

    Vielen Dank für die Antworten.

    @volkard:
    Deine Idee ist super, nur entfernt der Präprozessor nicht die "##" und ich bekomme einen Compiler-Error. Weißt du was ich falsch mache?

    Danke

    Volkard wechselt zwischen TIER und tier. Sollte er nicht. Du auch nicht.

    Außerdem sind das die Templates, hat Volkard auch schon geschrieben. Die musst du mit dem Präprozessor erstellen. Einfach

    tier ## _hallo
    

    Wird's nicht reißen, das muss über #define laufen.



  • Danke, ich verstehe es aber noch nicht.

    Wenn ich z.B. so etwas schreibe wie

    #define TIER katze 
    
    TIER_lauf(); 
    TIER_belle(); 
    TIER_spring;
    

    dann ist die Ausgabe des Präprozessors

    TIER_lauf(); 
    TIER_belle(); 
    TIER_spring;
    

    d.h. nichts wird ersetzt (da der Präprozessor keine Teil-Strings ersetzt).
    Wisst ihr wie ich dieses Problem umgehen kann?

    Danke


  • Mod

    So wie gezeigt.



  • Du meinst so:

    #define TIER katze 
    
    TIER##_lauf(); 
    TIER##_belle(); 
    TIER##_spring;
    

    Das hat bei mir nicht funktioniert, die Ausgabe war nämlich:

    katze##_lauf(); 
    katze##_belle(); 
    katze##_spring;
    

    Ich erhielt anschließend einen Compiler-Error wegen den übrig gebliebenen "##".


  • Mod

    Oh, ich vergesse immer, dass das so nicht geht. volkard anscheinend auch. Das sieht so aus wie etwas, das absolut gehen sollte 🙂

    Level 1:

    #define TIER(member) katze##_##member
    TIER(lauf)();   // katze_lauf();
    

    Level 2:

    // Irgendwo tief in einem Header versteckt:
    #define TIER_IMPL(tier, member) tier ##_## member
    #define TIER_PROXY(tier, member) TIER_IMPL(tier, member)
    #define TIER(member) TIER_PROXY(T_TIER, member)
    
    #define T_TIER katze   // Wird von dir bei Bedarf gesetzt
    
    TIER(lauf)();   // katze_lauf();
    


  • Besten Dank, genau so etwas habe ich gesucht.


Log in to reply