Un groupe de macros variadiques

Je voudrais avoir un groupe de nombre variable d’arguments passés dans une macro. J’ai les macros suivantes qui sont incorrectes:

#define M_NARGS(...) M_NARGS_(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) #define M_NARGS_(_10, _9, _8, _7, _6, _5, _4, _3, _2, _1, N, ...) N #define M_CONC(A, B) M_CONC_(A, B) #define M_CONC_(A, B) A##B #define M_ID(...) __VA_ARGS__ #define M_LEFT(L, R) L #define M_RIGHT(L, R) R #define M_FOR_EACH(ACTN, ...) M_CONC(M_FOR_EACH_, M_NARGS(__VA_ARGS__)) (ACTN, __VA_ARGS__) #define M_FOR_EACH_0(ACTN, E) E #define M_FOR_EACH_1(ACTN, E) ACTN(E) #define M_FOR_EACH_2(ACTN, E, ...) ACTN(E) M_FOR_EACH_1(ACTN, __VA_ARGS__) #define M_FOR_EACH_3(ACTN, E, ...) ACTN(E) M_FOR_EACH_2(ACTN, __VA_ARGS__) #define M_FOR_EACH_4(ACTN, E, ...) ACTN(E) M_FOR_EACH_3(ACTN, __VA_ARGS__) #define M_FOR_EACH_5(ACTN, E, ...) ACTN(E) M_FOR_EACH_4(ACTN, __VA_ARGS__) #define FRUITS (apple, banana, cherry) #define ANIMALS (dog, monkey) #define ZOO_BLOCK(NAME, FRTS, ANMLS) struct NAME##Block { \ M_FOR_EACH(DEFINE_FRUITS, FRTS) \ // Wrong, see my question below M_FOR_EACH(DEFINE_ANIMAL, ANMLS) \ // Wrong } #define DEFINE_FRUITS(F) Fruit F; #define DEFINE_ANIMALS(F) Animal F; ZOO_BLOCK(MyZoo, FRUITS, ANIMALS); 

Par M_FOR_EACH(DEFINE_FRUITS, FRTS) , j’aimerais faire M_FOR_EACH(DEFINE_FRUITS, __VA_ARGS__) et __VA_ARGS__ sont tous issus de FRUITS (pomme, banane, cerise). Comment puis-je changer mes macros pour faire cela?

    Je ne sais pas si c’est ce que vous recherchez, mais les groupes de fruits et d’animaux entre parenthèses ne sont pas résolus. Vous pouvez les “aplatir” avec votre macro M_ID , par exemple:

     #define M_ID(...) __VA_ARGS__ #define FRUITS M_ID(apple, banana, cherry) #define ANIMALS M_ID(dog, monkey) #define ZOO_BLOCK(NAME, FRTS, ANMLS) struct NAME##Block { \ M_FOR_EACH(DEFINE_FRUITS, FRTS) \ M_FOR_EACH(DEFINE_ANIMALS, ANMLS) \ } #define DEFINE_FRUITS(F) Fruit F; #define DEFINE_ANIMALS(F) Animal F; ZOO_BLOCK(MyZoo, FRUITS, ANIMALS); 

    Ceci, associé à la correction d’une faute de frappe mineure dans DEFINE_ANIMAL/S donne:

     struct MyZooBlock { Fruit apple; Fruit banana; Fruit cherry; Animal dog; Animal monkey; }; 

    Si vous voulez générer des structures basées sur des listes, j’utiliserais des macros d’ordre supérieur. Cela ne vous oblige pas à avoir une autre macro qui effectue la résolution de la boucle.

     #define FRUITS(V) \ V(apple) \ V(banana) \ V(cherry) #define ANIMALS(V) \ V(dog) \ V(monkey) #define VISIT_ANI_STRUCT(A) \ Animal A; #define VISIT_FRU_STRUCT(F) \ Fruit F; #define ZOO_BLOCK(NAME, GEN_ANI,GEN_FRU) \ struct NAME ## Block { \ ANIMALS(GEN_ANI) \ FRUITS(GEN_FRU) \ } ZOO_BLOCK(Zoo, VISIT_ANI_STRUCT, VISIT_FRU_STRUCT); 

    Aura pour résultat:

     struct ZooBlock { Animal dog; Animal monkey; Fruit apple; Fruit banana; Fruit cherry; }; 

    Ou si vous avez besoin du contraire

     #define ZOO_BLOCK(NAME, A, F) \ struct NAME ## Block { \ A(VISIT_ANI_STRUCT) \ F(VISIT_FRU_STRUCT) \ } ZOO_BLOCK(Zoo, VISIT_ANI_STRUCT, VISIT_FRU_STRUCT);