Frage zu Pointer Array.


  • Mod

    Boost Preprocessor kennt auch Argumentenlisten. Da brauchst du dann nur ein Makro für alle Variablen.



  • SeppJ schrieb:

    Boost Preprocessor kennt auch Argumentenlisten. Da brauchst du dann nur ein Makro für alle Variablen.

    ich kenne Boost preprocessor leider nicht so gut. Ich habe das Makro geschaut, leider konnte ich kein passendes Makro für

    #define DECLX_mybf(z, n, text) BOOST_PP_CAT(text, BOOST_PP_CAT(_, mybf)).push_back(&BOOST_PP_CAT(text, BOOST_PP_CAT(BOOST_PP_CAT(_, n), BOOST_PP_CAT(_, mybf))));
    
    BOOST_PP_REPEAT_FROM_TO(0, 2, DECLX_mybf, x);
    // generiert: x_mybf.push_back(&x_0_mybf); x_mybf.push_back(&x_1_mybf);
    

    finden. 😞

    Kannst du mehren Hinweis mir geben?

    Danke.

    Viele Grüße,

    /Kenny



  • sowohl

    BOOST_PP_REPEAT(count, macro, data)
    

    als auch

    BOOST_PP_REPEAT_FROM_TO(first, last, macro, data)
    

    können nur ein Makroform

    macro(z, n, data)
    

    akzeptieren.

    Welche Makro kann ich nutzen, um mehr als ein Argument zu geben?

    Danke.

    /Kenny



  • mybfclass x_0_mybf;
    mybfclass x_1_mybf;
    ...
    mybfclass1 x_0_mybf1;
    mybfclass1 x_1_mybf1;
    ...
    mybfclass2 x_0_mybf2;
    mybfclass2 x_1_mybf2;
    ...
    

    Für sowas kannst du die Makros verschachteln. Ähnlich wie bei einer doppelten Schleife gehst du zuerst den einen Index durch, dann den anderen.

    Für den Spezialfall, dass beim Index 0 keine Null steht, sondern nichts, kannst du dir sowas einrichten:

    #define NUMBER(N) BOOST_PP_IF(BOOST_PP_EQUAL(N, 0), , N)
    #define DECL(Z, N, DATA) BOOST_PP_CAT(Decl, NUMBER(N))
    
    int main()
    {
    	BOOST_PP_REPEAT(4, DECL, )
    }
    

    Expandiert zu:

    int main()
    {
    	Decl Decl1 Decl2 Decl3
    }
    

    Man hat eigentlich nicht wenige Möglichkeiten zur Präprozessor-Metaprogrammierung. 😉


  • Mod

    Mit der Argumentenliste meinte ich, dass man eine Liste als ein Argument geben kann. Oder eine Sequence, weil die einfacher zu handhaben sind. Und die Sequence lässt man dann vom eigentlichen Makro wieder in die einzelnen Argumente zerpflücken. Funktioniert ziemlich gut.

    @Nexus: Das Verschachteln von Schleifen geht (zumindest bei boost) oftmals nicht. Zumindest wenn man den gleichen Schleifentyp im Inneren und im Äußeren benutzt. Dann muss man stattdessen beispielsweise eine for-Schleife innerhalb einer while-Schleife machen. Das funktioniert dann aber ganz ausgezeichnet.



  • SeppJ schrieb:

    Mit der Argumentenliste meinte ich, dass man eine Liste als ein Argument geben kann. Oder eine Sequence, weil die einfacher zu handhaben sind. Und die Sequence lässt man dann vom eigentlichen Makro wieder in die einzelnen Argumente zerpflücken. Funktioniert ziemlich gut.

    @Nexus: Das Verschachteln von Schleifen geht (zumindest bei boost) oftmals nicht. Zumindest wenn man den gleichen Schleifentyp im Inneren und im Äußeren benutzt. Dann muss man stattdessen beispielsweise eine for-Schleife innerhalb einer while-Schleife machen. Das funktioniert dann aber ganz ausgezeichnet.

    ich habe folgendes Makro mit Argumentlistmethode geschrieben, und es hat gut funktioniert:

    #define DECLX_BF(z, n, text) BOOST_PP_CAT(BOOST_PP_LIST_AT(text, 0), BOOST_PP_CAT(_, BOOST_PP_LIST_AT(text, 1))).push_back(\
    &BOOST_PP_CAT(BOOST_PP_LIST_AT(text, 0), BOOST_PP_CAT(_, BOOST_PP_CAT(n, BOOST_PP_CAT(_, BOOST_PP_LIST_AT(text, 1))))));
    
    // user code
    BOOST_PP_REPEAT_FROM_TO(0, 2, DECLX_BF, (x, (mybf, BOOST_PP_NIL)));
    BOOST_PP_REPEAT_FROM_TO(0, 2, DECLX_BF, (x, (mybf1, BOOST_PP_NIL)));
    BOOST_PP_REPEAT_FROM_TO(0, 2, DECLX_BF, (x, (mybf2, BOOST_PP_NIL)));
    // generiert: x_mybf.push_back(&x_0_mybf); x_mybf.push_back(&x_1_mybf); 
    // und x_mybf1.push_back(&x_0_mybf1); x_mybf1.push_back(&x_1_mybf1);
    // und x_mybf2.push_back(&x_0_mybf2); x_mybf2.push_back(&x_1_mybf2);
    

    jetzt bekämpfe ich eine 2-dimensionale Array

    reg1[0][0] = &reg1_IFA_0;
    reg1[0][1] = &reg1_IFA_1;
    reg1[0][2] = &reg1_IFA_2;
    ...
    reg1[1][0] = &reg1_IFB_0;
    reg1[1][1] = &reg1_IFB_1;
    reg1[1][2] = &reg1_IFB_2;
    ...
    ich denke, es sollte leichte gemacht werden kann. Ich werde meine Lösung nochmal zum Review posten.

    vielen Dank für deinen Hinweis.

    /Kenny



  • SeppJ schrieb:

    @Nexus: Das Verschachteln von Schleifen geht (zumindest bei boost) oftmals nicht. Zumindest wenn man den gleichen Schleifentyp im Inneren und im Äußeren benutzt. Dann muss man stattdessen beispielsweise eine for-Schleife innerhalb einer while-Schleife machen. Das funktioniert dann aber ganz ausgezeichnet.

    Hm. Also mit dem folgenden Code habe ich keine Probleme:

    #include <boost/preprocessor/repetition.hpp>
    #include <iostream>
    
    #define INNER(Z, INNER_VAR, OUTER_VAR) std::cout << OUTER_VAR << " " << INNER_VAR << std::endl;
    #define OUTER(Z, OUTER_VAR, INNER_MAX) BOOST_PP_REPEAT(INNER_MAX, INNER, OUTER_VAR)
    
    #define CASCADED(OUTER_MAX, INNER_MAX) BOOST_PP_REPEAT(OUTER_MAX, OUTER, INNER_MAX)
    
    int main()
    {
    	CASCADED(5, 3)
    }
    

    Ich weiss nicht, ob du vielleicht das meinst, aber die Boost-Präprozessormagier schreiben auf ihrer Seite zu BOOST_PP_REPEAT_z :

    <a href= schrieb:

    BOOST_PP_REPEAT Dokumentation">Previously, this macro could not be used recursively inside BOOST_PP_REPEAT. This limitation no longer exists, as the library can automatically detect the next available repetition depth.


  • Mod

    Nexus schrieb:

    Ich weiss nicht, ob du vielleicht das meinst, aber die Boost-Präprozessormagier schreiben auf ihrer Seite zu BOOST_PP_REPEAT_z :

    <a href= schrieb:

    BOOST_PP_REPEAT Dokumentation">Previously, this macro could not be used recursively inside BOOST_PP_REPEAT. This limitation no longer exists, as the library can automatically detect the next available repetition depth.

    Ja, ist ein schon Weilchen her, dass ich das festgestellt hatte. Gut zu wissen.



  • habe endlich das Problem mit Argumentlist gelöst:

    ich habe folgendes geschrieben:

    #define DECLX_1D(z, n, text) BOOST_PP_LIST_AT(text, 1)[BOOST_PP_LIST_AT(text, 0)][n] = \
    &BOOST_PP_CAT(BOOST_PP_LIST_AT(text, 1), BOOST_PP_CAT(_, BOOST_PP_CAT(BOOST_PP_LIST_AT(text, 0), BOOST_PP_CAT(_, n))));
    #define DECLX_REG_2D(z, n, text) BOOST_PP_REPEAT_FROM_TO(0, BOOST_PP_LIST_AT(text, 0), DECLX_1D, (n, (BOOST_PP_LIST_AT(text, 1), BOOST_PP_NIL)));
    
    int reg_0_0 = 12;
    int reg_0_1 = 13;
    int reg_1_0 = 14;
    int reg_1_1 = 15;
    
    int *reg[2][2];
    
    BOOST_PP_REPEAT_FROM_TO(0, 2, DECLX_REG_2D, (2, (reg, BOOST_PP_NIL)));
    
    // generiert: reg[0][0] = &reg_0_0; reg[0][1] = &reg_0_1;
    // reg[1][0] = &reg_1_0; reg[1][1] = &reg_1_1;
    

    das Makro siehst einbisschen kompliziert aus, oder?

    Nexus: mit deiner Methode werde ich mal probieren. _z Version sieht aus erstem Blick gut aus.

    Danke für eure Hilfe, ich denke, ich kann meine Codemenge sehr stark reduzieren, und gleichzeitlich kann ich jetzt besser das Code verwalten.

    /Kenny


  • Mod

    tjroamer schrieb:

    das Makro siehst einbisschen kompliziert aus, oder?

    Ja, aus meiner Erfahrung ist das bei der Präprozessormetaprogrammierung immer so. Aber solch ein Makro schreibt man einmal und versteckt es dann irgendwo in einem Header und dann sieht alles wieder ordentlich aus.


Anmelden zum Antworten