Schleife in Präprozessor-Anweisung?



  • Hallo,

    bin relativ neu in C++ und habe daher folgende Frage: ist es möglich, im Präprozessor von C++ Schleifen einzubauen?

    Grund: Ich habe in meinem Programm eine Anweisung, die sich 20 Mal wiederholt und sich dabei aber nur eine Zahl pro Anweisung ändert. Jetzt habe ich für diese Anweisung eine Präprozessor-Funktion geschrieben, die mir die Anweisung ausgibt und an der entsprechenden Stelle die Zahl ändert. Allerdings sieht es jetzt statt

    gaaaaaaaaaaaaaaaanzLaaaaaaaaaaangeAnweisung(x,y,z,1);
    gaaaaaaaaaaaaaaaanzLaaaaaaaaaaangeAnweisung(x,y,z,2);
    gaaaaaaaaaaaaaaaanzLaaaaaaaaaaangeAnweisung(x,y,z,3);
    ......
    gaaaaaaaaaaaaaaaanzLaaaaaaaaaaangeAnweisung(x,y,z,20);

    folgendermaßen aus:

    PREPROC(1);
    PREPROC(2);
    PREPROC(3);
    ......
    PREPROC(20);

    d.h. ich habe zwar die Anweisung verkürzt, aber nicht die Anzahl. Wenn ich jetzt also eine Präprozessor-Funktion schreiben könnte, die gleiche alle 20 Anweisungen schreibt, würde ich mir 19 Zeilen sparen. Ich suche also etwas wie folgendes:

    #define PREPROC(anzahl) { \
    	for (i=0; <anzahl; i++) { \
    		gaaaaaaaaaaaaaaaanzLaaaaaaaaaaangeAnweisung(x,y,z,i); \
    	}
    

    so dass ich also nur einmal PREPROC(20); aufrufen muss, und alles ist erledigt.

    Gibt es sowas? Oder bin ich der einzige, der das Problem hat? Klar kann man es auch über eine normale C++ Funktion lösen, aber ich fände Preprocessor besser...

    Danke schon mal!
    gehho



  • wenn Du in der Schleife noch i definierst müsste es eigentlich funktionieren.

    Allerdings, was hast Du gegen eine normale C++ funktion? Wenn es um den Funcion-Calling-Overhead geht canst du sie ja inlinen

    inline void PREPROC(int anzahl)
    {
        for (int i = 0; i < anzahl; i++)
            gaaaaaaaaaaaaaaaaaaanzLaaaaaaaaaaaaaangeAnweisung(x, y, z, i);
    }
    


  • Knecht schrieb:

    Allerdings, was hast Du gegen eine normale C++ funktion? Wenn es um den Funcion-Calling-Overhead geht canst du sie ja inlinen

    Is sowieso besser, denn Präprozessor ist böse ⚠ (natürlich mit best. Ausnahmen :p ).



  • mach's doch mit 'nem c++ template. ist ja sowas ähnliches wie der preprozessor



  • das problem ist, dass es sich bei der zahl um den teil eines variablennamens handelt. um genau zu sein, verwende ich die funktion beim connecten meiner button-signale und -slots in qt. d.h. für eine normale funktion müsste ich mir ein array der buttons erzeugen und dieses an die funktion übergeben. dadurch entstehen wieder einige codezeilen, um die buttons dem array hinzuzufügen. außerdem wäre es aufwändig zu handhaben, wenn neue buttons hinzu kommen. wäre also kein wirklicher gewinn. es sei denn ihr habt noch andere ideen.

    in meiner preprocessor-funktion löse ich das eben durch "button##i", dann hängt der mir ja die zahl i einfach an "button" an. in einer schleife funktioniert das aber nicht. da sagt er dann "buttonk has not been defined..." (k ist meine zählvariable in der schleife). das heißt, er setzt nicht die zahl ein, für die k steht, sondern den buchstaben k.

    naja, ist nicht ganz so wichtig das thema, aber wenn ihr noch ne gute idee dazu habt, wäre ich trotzdem dankbar!

    gehho.



  • Spontaneinfall: Pack die Buttons gleich in ein Array.



  • Lass mich mal sehen ob ich dass richtig verstanden habe, obwohl ich QT nicht kenne. Du hast irgendwo ein header-file (z.B resource.h bei WinAPI) in dem zahlreiche #define für deine Button-namen stehen?

    Wenn das so ist funktioniert es mit der schleife nur, wenn die Nummmern hinter den defines fortlaufend sind.

    z.B

    #defnie BUTTON_1    1000
    #defnie BUTTON_2    1001
    #defnie BUTTON_3    1002
    #defnie BUTTON_4    1003
    
    inline void Preproc(int ersterButton, int letzerButton)
    {
        for (int i = ersterButton; i <= letzerButton; i++)
            // ... hier muss dann direkt der Aufruf für deine Buttons stehen
            // edit: mit i anstelle des Button-Makros
    }
    

    Der Aufruf im Programm erfolgt dann mit den Makros für den ersten und den letzten Button

    z.B

    Preproc(BUTTON_1, BUTTON_4);
    

    Hintergrund ist folgender:
    Der Preprocessor ersetzt die Namen durch die zugeordneten Nummern. Zur Laufzeit des Compilers stehen also anstatt der Namen der Makros deren zugeordnete Nummern im Code mit denen die entsprechende Funktion die Buttons lädt. Schleifen werden allerdings nicht zur Compile-Zeit durchlaufen sondern zur Laufzeit, also nutzt dir die Schleife im Preprocessor nichts, da zur Laufzeit die Makro-Namen nicht mehr durch die Nummern ersetzt werden. Du kannst diese Nummern, sofern sie fortlaufend sind, ja aber von der Funktion nur direkt zum aufruf der Buttons verwenden. 😉

    War das jetzt zu verwirrend? 😕



  • Ja es ist möglich Schleifen mit dem Preprocessor zu bauen. Dies ist allerdings recht umständlich zu implementiren allerdings kann man auch einfach die Boost Version nehmen:

    #include<boost/preprocessor/repetition/repeat_from_to.hpp>
    //...
    #define MY_FUNC(z, n, data)\
      gaaaaaaaaaaaaaaaanzLaaaaaaaaaaangeAnweisung(x,y,z,n); 
    BOOST_PP_REPEAT_FROM_TO(1, 20, MY_FUNC, no_data)
    #undef MY_FUNC
    

    Allerdigns bin ich mir ziemlich sicher, dass du mit einem Array besser dran wärest.


Anmelden zum Antworten